httpcomponents-client-4.3.3/0040755 0000000 0000000 00000000000 12302131604 014604 5ustar000000000 0000000 httpcomponents-client-4.3.3/BUILDING.txt0100644 0000000 0000000 00000002356 12301751651 016556 0ustar000000000 0000000 Building HttpComponents Client ============================ (1) Requisites -------------- JDK 1.5+ is required in order to compile and run HttpClient. HttpClient utilizes Maven as a distribution management and packaging tool. Version 3.0.3 or later is required. Maven installation and configuration instructions can be found here: http://maven.apache.org/run-maven/index.html (2) Executing test cases Execute the following command in order to compile and test the components mvn test (3) Building packages Execute the following command in order to build the JAR packages and install them to the local repository: mvn install The JAR packages can be found in the target folders of their respective modules httpclient/target/httpclient-.jar httpmime/target/httpmime-.jar httpclient-cache/target/httpclient-cache-.jar fluent-hc/target/fluent-hc-.jar httpclient-osgi/target/org.apache.httpcomponents.httpclient_.jar where is the release version (4) Building documentation Execute the following command in order to generate javadoc: mvn javadoc:aggregate Execute the following command in order to generate the tutorial in html and pdf formats mvn docbkx:generate-pdf docbkx:generate-html httpcomponents-client-4.3.3/LICENSE.txt0100644 0000000 0000000 00000023675 12301751651 016452 0ustar000000000 0000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS httpcomponents-client-4.3.3/NOTICE.txt0100644 0000000 0000000 00000000267 12301751651 016341 0ustar000000000 0000000 Apache HttpComponents Client Copyright 1999-2014 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). httpcomponents-client-4.3.3/pom.xml0100644 0000000 0000000 00000036106 12301751746 016142 0ustar000000000 0000000 project org.apache.httpcomponents 7 ../project/pom.xml 4.0.0 httpcomponents-client HttpComponents Client 4.3.3 Apache HttpComponents Client is a library of components for building client side HTTP services http://hc.apache.org/httpcomponents-client 1999 pom The Apache Software Foundation http://www.apache.org/ Apache License, Version 2.0 LICENSE.txt repo Jira http://issues.apache.org/jira/browse/HTTPCLIENT scm:svn:https://svn.apache.org/repos/asf/httpcomponents/httpclient/tags/4.3.3 scm:svn:https://svn.apache.org/repos/asf/httpcomponents/httpclient/tags/4.3.3 https://svn.apache.org/repos/asf/httpcomponents/httpclient/tags/4.3.3 4.3.2 1.1.3 1.6 2.2.0 2.6 1.5.11 4.9 2.5.2 1.8.5 4.0.0 1 4.3 spy Spy Repository default http://files.couchbase.com/maven2/ false org.apache.httpcomponents httpcore ${httpcore.version} commons-logging commons-logging ${commons-logging.version} commons-codec commons-codec ${commons-codec.version} net.sf.ehcache ehcache-core ${ehcache.version} org.slf4j slf4j-jcl ${slf4j.version} spy spymemcached ${memcached.version} net.java.dev.jna jna ${jna.version} net.java.dev.jna jna-platform ${jna.version} junit junit ${junit.version} test org.mockito mockito-core ${mockito.version} test org.easymock easymock ${easymock.version} test org.easymock easymockclassextension ${easymock.version} test httpclient httpmime fluent-hc httpclient-cache httpclient-osgi maven-jar-plugin HttpComponents ${project.name} ${project.version} The Apache Software Foundation HttpComponents ${project.name} ${project.version} The Apache Software Foundation org.apache ${project.url} maven-source-plugin attach-sources jar HttpComponents ${project.name} ${project.version} The Apache Software Foundation HttpComponents ${project.name} ${project.version} The Apache Software Foundation org.apache maven-javadoc-plugin attach-javadocs jar true ${maven.compiler.source} http://download.oracle.com/javase/1.5.0/docs/api/ http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/ com.agilejava.docbkx docbkx-maven-plugin org.docbook docbook-xml 4.4 runtime tutorial-site generate-html generate-pdf pre-site index.xml true true src/docbkx/resources/xsl/fopdf.xsl src/docbkx/resources/xsl/html_chunk.xsl css/hc-tutorial.css version ${project.version} maven-resources-plugin copy-resources pre-site copy-resources ${basedir}/target/site/examples src/examples false org.codehaus.mojo clirr-maven-plugin ${api.comparison.version} org.apache.maven.plugins maven-checkstyle-plugin 2.9.1 org.apache.httpcomponents hc-stylecheck ${hc.stylecheck.version} UTF-8 validate-main validate hc-stylecheck/default.xml hc-stylecheck/asl2.header true true false ${basedir}/src/main checkstyle validate-test validate hc-stylecheck/default.xml hc-stylecheck/asl2.header true true false ${basedir}/src/test checkstyle validate-examples validate hc-stylecheck/minimal.xml hc-stylecheck/asl2.header true true false ${basedir}/src/examples checkstyle org.codehaus.mojo clirr-maven-plugin ${hc.clirr.version} ${api.comparison.version} maven-project-info-reports-plugin ${hc.project-info.version} false dependency-management issue-tracking license scm summary org.codehaus.mojo clirr-maven-plugin ${hc.clirr.version} ${api.comparison.version} httpcomponents-client-4.3.3/README.txt0100644 0000000 0000000 00000005103 12301751651 016307 0ustar000000000 0000000 Apache HttpComponents Client ============================ Welcome to the HttpClient component of the Apache HttpComponents project. Building Instructions --------------------- For building from source instructions please refer to BUILDING.txt. Dependencies ------------ HttpClient main module requires Java 5.0 compatible runtime and depends on the following external libraries: * Apache HttpComponents HttpCore * Apache Commons Logging * Apache Commons Codec (for detailed information on external dependencies please see pom.xml) HttpMime module is optional and requires Java 5.0 compatible runtime and depends on the following external libraries: * Apache HttpComponents HttpCore * Apache Commons Logging (for detailed information on external dependencies please see pom.xml) Licensing --------- Apache HttpComponents Client is licensed under the Apache License 2.0. See the files called LICENSE.txt and NOTICE.txt for more information. Cryptographic Software Notice ----------------------------- This distribution may include software that has been designed for use with cryptographic software. The country in which you currently reside may have restrictions on the import, possession, use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check your country's laws, regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. See for more information. The U.S. Government Department of Commerce, Bureau of Industry and Security (BIS), has classified this software as Export Commodity Control Number (ECCN) 5D002.C.1, which includes information security software using or performing cryptographic functions with asymmetric algorithms. The form and manner of this Apache Software Foundation distribution makes it eligible for export under the License Exception ENC Technology Software Unrestricted (TSU) exception (see the BIS Export Administration Regulations, Section 740.13) for both object code and source code. The following provides more details on the included software that may be subject to export controls on cryptographic software: Apache HttpComponents Client interfaces with the Java Secure Socket Extension (JSSE) API to provide - HTTPS support Apache HttpComponents Client does not include any implementation of JSSE. Contact ------- o For general information visit the main project site at http://hc.apache.org/ o For current status information visit the status page at http://hc.apache.org/status.html httpcomponents-client-4.3.3/RELEASE_NOTES.txt0100644 0000000 0000000 00000221400 12301751651 017402 0ustar000000000 0000000 Release 4.3.3 ------------------- HttpClient 4.3.3 (GA) is a bug fix release that fixes a regression introduced by the previous release causing a significant performance degradation in compressed content processing. Users of HttpClient 4.3 are encouraged to upgrade. Changelog: ------------------- * [HTTPCLIENT-1466] FileBodyPart#generateContentType() ignores custom ContentType values. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1453] Thread safety regression in PoolingHttpClientConnectionManager #closeExpiredConnections that can lead to ConcurrentModificationException. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1461] fixed performance degradation in compressed content processing introduced by HTTPCLIENT-1432. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1457] Incorrect handling of Windows (NT) credentials by SystemDefaultCredentialsProvider. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1456] Request retrial after status 503 causes ClientProtocolException. Contributed by Oleg Kalnichevski Release 4.3.2 ------------------- HttpClient 4.3.2 (GA) is a maintenance release that delivers a number of improvements as well as bug fixes for issues reported since 4.3.1 release. SNI support for Oracle JRE 1.7+ is being among the most notable improvements. Users of HttpClient 4.3 are encouraged to upgrade. Changelog: ------------------- * [HTTPCLIENT-1447] Clients created with HttpClients.createMinimal do not work with absolute URIs Contributed by Joseph Walton * [HTTPCLIENT-1446] NTLM proxy + BASIC target auth fails with 'Unexpected state: MSG_TYPE3_GENERATED'. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1443] HttpCache uses the physical host instead of the virtual host as a cache key. Contributed by Francois-Xavier Bonnet * [HTTPCLIENT-1442] Authentication header set by the user gets removed in case of proxy authentication (affects plan HTTP requests only). Contributed by Oleg Kalnichevski * [HTTPCLIENT-1441] Caching AsynchronousValidationRequest leaks connections. Contributed by Dominic Tootell * [HTTPCLIENT-1440] 'file' scheme in redirect location URI causes NPE. Contributed by James Leigh * [HTTPCLIENT-1437] Made Executor#execute thread safe. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1119] SNI support (Oracle Java 1.7+ only). Contributed by Bruno Harbulot * [HTTPCLIENT-1435] Fluent Executor ignores custom request properties. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1432] Lazy decompressing of HttpEntity#getContent() to avoid EOFException in case of an empty response with 'Content-Encoding: gzip' header. Contributed by Yihua Huang * [HTTPCLIENT-1431] (Regression) deprecated connection manager cannot be used with a custom LayeredSchemeSocketFactory. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1425] Fixed socket closed exception thrown by caching HttpClient when the origin server sends a long chunked response. Contributed by James Leigh * [HTTPCLIENT-1417] Fixed NPE in BrowserCompatSpec#formatCookies caused by version 1 cookies with null cookie value. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1416] Fixed NPE in CachingHttpClientBuilder#build(). Contributed by Oleg Kalnichevski Release 4.3.1 ------------------- HttpClient 4.3.1 (GA) is a bug fix release that addresses a number of issues reported since release 4.3. Users of HttpClient 4.3 are strongly encouraged to upgrade. Changelog ------------------- * [HTTPCLIENT-1410] Browser compatible hostname verifier no longer rejects *.co., *.gov., *.info., etc as invalid. Contributed by Oleg Kalnichevski * Ensure X509HostnameVerifier is never null. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1405] CONNECT HTTP/1.1 requests lack mandatory 'Host' header. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1402] Cache default User-Agent value. Contributed by yuexiaojun * [HTTPCLIENT-1398] Fixed invalid OSGi metadata caused by corrupted Maven bundle plugin metadata. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1399] Fixed NPE in RequestBuilder. Contributed by Oleg Kalnichevski Release 4.3 Final ------------------- This is the first stable (GA) release of HttpClient 4.3. The most notable enhancements included in this release are: * Support for Java 7 try-with-resources for resource management (connection release.) * Added fluent Builder classes for HttpEntity, HttpRequest, HttpClient and SSLContext instances. * Deprecation of preference and configuration API based on HttpParams interface in favor of constructor injection and plain configuration objects. * Reliance on object immutability instead of access synchronization for thread safety. Several old classes whose instances can be shared by multiple request exchanges have been replaced by immutable equivalents. * DefaultHttpClient, DecompressingHttpClient, CachingHttpClient and similar classes are deprecated in favor of builder classes that produce immutable HttpClient instances. * HttpClient builders now dynamically construct a request execution pipeline tailored specifically to the user configuration by physically excluding unnecessary protocol components. * There is now an option to construct a minimal HttpClient implementation that can only execute basic HTTP message exchanges without redirects, authentication, state management or proxy support. This feature might be of particular use in web crawler development. * There is now option to avoid strict URI syntax for request URIs by executing HTTP requests with an explicitly specified target host. HttpClient will no longer attempt to parse the request URI if it does not need to extract the target host from it. This release also includes all fixes from the stable 4.2.x release branch. Changelog ------------------- * [HTTPCLIENT-1371] Weak ETag Validation is Useful On PUT With If-Match Contributed by James Leigh * [HTTPCLIENT-1394] Support for Native windows Negotiate/NTLM via JNA Contributed by Ryan McKinley * [HTTPCLIENT-1384] Expose CacheInvalidator interface. Contributed by Nicolas Richeton * [HTTPCLIENT-1385] Fixed path normalization in CacheKeyGenerator Contributed by James Leigh * [HTTPCLIENT-1370] Response to non-GET requests should never be cached with the default ResponseCachingPolicy Contributed by James Leigh * [HTTPCLIENT-1373] OPTIONS and TRACE should not invalidate cache Contributed by James Leigh * [HTTPCLIENT-1383] HttpClient enters an infinite loop during NTLM authentication if the opposite endpoint keeps responding with a type 2 NTLM response after type 3 MTLM message has already been sent by the client. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1372] Refactor HttpMultipart, and add RFC6532 mode, so that headers in post are no longer constrained to ASCII values. Contributed by Karl Wright * [HTTPCLIENT-1377] User principal for non-NTLM authentication is incorrectly generated when using user credentials are specified as NTCredentials Contributed by Gary Gregory Release 4.3 BETA2 ------------------- This is the second BETA release of HttpClient 4.3. The most notable features and improvements in the 4.3 branch are: Support for Java 7 try-with-resources for resource management (connection release); fluent Builder classes for HttpEntity, HttpRequest and HttpClient instances, deprecation of preference and configuration API based on HttpParams interface in favor of constructor injection and plain configuration objects, reliance on object immutability instead of access synchronization for thread safety. This release also includes all fixes from the stable 4.2.x release branch. Changelog ------------------- * [HTTPCLIENT-1366] org.apache.http.client.utils.URLEncodedUtils should parse the semicolon as a query parameter separator. Contributed by Gary Gregory * [HTTPCLIENT-1365] NPE when ManagedHttpClientConnectionFactory.create(ConnectionConfig) is called with null. Contributed by Gary Gregory * [HTTPCLIENT-1362] Better error messages for connect timed out and connection refused exceptions. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1360] separate out DeflateInputStream as an independent class, so it can be used by others. Contributed by Karl Wright * [HTTPCLIENT-1359] repeated requests using the same context fail if they redirect. Contributed by James Leigh * [HTTPCLIENT-1354] do not quote algorithm parameter in DIGEST auth response. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1351] Added utility method to resolve final location from original request, target host and a list of redirects. Contributed by James Leigh * [HTTPCLIENT-1344] Userinfo credentials in URI should not default to preemptive BASIC authentication. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1345] Useinfo credentials ignored in redirect location header. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1294] HttpClient to rewrite host name of the redirect location URI in order to avoid circular redirect exception due to host name case mismatch. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1264] Add support for multiple levels of browser compatibility to BrowserCompatSpec and BrowserCompatSpecFactory. Include constructor argument for IE medium-security compatibility. Contributed by Karl Wright (kwright at apache.org) * [HTTPCLIENT-1349] SSLSocketFactory incorrectly identifies key passed with keystore as the keystore password. Contributed by David Graff * [HTTPCLIENT-1346] Ensure propagation of SSL handshake exceptions. Contributed by Pasi Eronen * [HTTPCLIENT-1343] SSLSocketFactory optional parameters for supported SSL protocols and cipher suites. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1238] Contribute Bundle Activator And Central Proxy Configuration. Contributed by Simone Tripodi * [HTTPCLIENT-1299] (regression) cache incorrectly disposes of the underlying cache resource when storing variant entry. Contributed by James Leigh * [HTTPCLIENT-1342] Redirects with underscore character in the location hostname cause "java.lang.IllegalArgumentException: Host name may not be null". Contributed by Oleg Kalnichevski Release 4.3 BETA1 ------------------- This is the first BETA release of HttpClient 4.3. The 4.3 branch enhances HttpClient in several key areas and includes several notable features and improvements: Support for Java 7 try-with-resources for resource management (connection release); fluent Builder classes for HttpEntity, HttpRequest and HttpClient instances, deprecation of preference and configuration API based on HttpParams interface in favor of constructor injection and plain configuration objects, reliance on object immutability instead of access synchronization for thread safety. This release also includes all fixes from the stable 4.2.x release branch. Changelog ------------------- * [HTTPCLIENT-1317] InetAddressUtils should handle IPv6 Addresses with Embedded IPv4 Addresses Contributed Sebastian Bazley . * [HTTPCLIENT-1320] Leverage javax.net.ssl.SSLSocketFactory#getDefault() to initialize SSL context based on system defaults instead of using an internal custom routine. Contributed by Abe Backus and Oleg Kalnichevski * [HTTPCLIENT-1316] Certificate verification rejects IPv6 addresses which are not String-equal. Contributed Sebastian Bazley . * [HTTPCLIENT-1307] Future based asynchronous request execution. Contributed by Jilles van Gurp * [HTTPCLIENT-1313] Fixed IllegalStateException in deprecated ThreadSafeClientConnManager. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1298] Add AsynchronousValidator in HttpClientBuilder's list of closeable objects. Contributed by Martin Meinhold Release 4.3 ALPHA1 ------------------- This is the first ALPHA release of HttpClient 4.3. The 4.3 branch enhances HttpClient in several key areas and includes several notable features and improvements: Support for Java 7 try-with-resources for resource management (connection release); fluent Builder classes for HttpEntity, HttpRequest and HttpClient instances, deprecation of preference and configuration API based on HttpParams interface in favor of constructor injection and plain configuration objects, reliance on object immutability instead of access synchronization for thread safety. We are kindly asking all upstream projects to review API changes and help us improve the APIs by providing feedback and sharing ideas on dev@hc.apache.org. This release also includes all fixes from the stable 4.2.x release branch. Please note that new features included in this release are still considered experimental and their API may change in the future 4.3 alpha and beta releases. Changelog ------------------- * [HTTPCLIENT-1250] Allow query string to be ignored when determining cacheability for HTTP 1.0 responses. Contributed by Don Brown * [HTTPCLIENT-1261] Make SystemDefaultHttpClient honor http.agent system property. Contributed by Oleg Kalnichevski * [HTTPCLIENT-900] Don't enforce URI syntax for messages with an explicit target host. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1190] HttpClient cache does not support "Vary: Cookie" Contributed by Oleg Kalnichevski * [HTTPCLIENT-1259] Calling #abort() on requests executed with DecompressingHttpClient has no effect. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1253] URIBuilder setParameter() method could exceed the HTTP header size. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1216] Added method to force clean thread-local used by DateUtils. Contributed by Oleg Kalnichevski Release 4.2.3 ------------------- HttpClient 4.2.3 (GA) is a bug fix release that addresses a number of issues reported since release 4.2.2. This release also includes a thoroughly reworked NTLM authentication engine which should result in a better compatibility with the newest Microsoft products. Users of HttpClient 4.x are advised to upgrade. Changelog ------------------- * [HTTPCLIENT-1296] NPE gets thrown if you combine a default host with a virtual host that has a -1 value for the port. Contributed by Karl Wright * [HTTPCLIENT-1290] 304 cached response never reused with If-modified-since conditional requests. Contributed by Francois-Xavier Bonnet * [HTTPCLIENT-1291] Absolute request URIs without an explicitly specified path are rewritten to have "/" path). Contributed by Oleg Kalnichevski * [HTTPCLIENT-1286] Request URI rewriting is inconsistent - URI fragments are not removed from absolute request URIs. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1284] HttpClient incorrectly generates Host header when physical connection route differs from the host name specified in the request URI. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1293] Kerberos and SPNego auth schemes use incorrect authorization header name when authenticating with a proxy. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1283] NTLM needs to use Locale-independent form of toUpperCase(). Contributed by Karl Wright * [HTTPCLIENT-1279] Target host responding with status 407 (proxy authentication required) causes an NPE. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1281] GzipDecompressingEntity does not release InputStream when an IOException occurs while reading the Gzip header Contributed by Francois-Xavier Bonnet * [HTTPCLIENT-1277] Caching client sends a 304 to an unconditional request. Contributed by Francois-Xavier Bonnet * [HTTPCLIENT-1278] Update NTLM documentation. Contributed by Karl Wright * SystemDefaultHttpClient misinterprets 'http.keepAlive' default value and disables connection persistence if the system property is not set. This causes connection based authentication schemes such as NTLM to fail. * [HTTPCLIENT-1276] cache update on a 304 response causes NPE. Contributed by Francois-Xavier Bonnet * [HTTPCLIENT-1273] DecompressingHttpClient does not automatically consume response content in case of an i/o, HTTP or runtime exception thrown by the decompressing protocol interceptor leading to a potential connection leak. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1268] NTLM engine refactor fix, to correct a buffer overrun, and get NTLMv2 flags right. Contributed by Karl Wright * [HTTPCLIENT-1266] NTLM engine refactoring and compatibility improvements. Contributed by Karl Wright * [HTTPCLIENT-1263] BrowserCompatSpec: attribute values containing spaces or special characters should be enclosed with quotes marks for version 1 cookies. Contributed by Francois-Xavier Bonnet * [HTTPCLIENT-1263] CachingHttpClient fails to release connections back to the connection manager for some type of HTTP response messages when used together with DecompressingHttpClient. Contributed by Francois-Xavier Bonnet * [HTTPCLIENT-1258] Fixed NullPointerException in NTLMEngineImpl caused by null NT domain attribute. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1254] Redirect with underscore in hostname causes ProtocolException. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1255] AbstractVerifier incorrectly parses certificate CN containing wildcard. Contributed by Oleg Kalnichevski Release 4.2.2 ------------------- HttpClient 4.2.2 (GA) is a bug fix release that addresses a number of issues reported since release 4.2.1. Users of HttpClient 4.2 are advised to upgrade. Changelog ------------------- * [HTTPCLIENT-1248] Default and lax redirect strategies should not convert requests redirected with 307 status to GET method. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1215] BasicAuthCache does not take default ports into consideration when looking up cached authentication details by HttpHost key. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1241] (regression) Preemptive BASIC authentication failure should be considered final and no further attempts to re-authenticate using the same credentials should be made. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1229] Fixed NPE in BasicClientConnectionManager that can be triggered by releasing connection after the connection manager has already been shut down. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1227] Date parsing in DateUtils made more efficient. Contributed by Patrick Linskey * [HTTPCLIENT-1224] (regression) NTLM auth not retried after a redirect over a non-persistent connection. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1223] Cache could be more aggressive on cache invalidations from Content-Location. Contributed by Jon Moore . Contributed by Jon Moore * [HTTPCLIENT-1217] AutoRetryHttpClient does not release connection used by the previous response when request is retried Contributed by Oleg Kalnichevski Release 4.2.1 ------------------- HttpClient 4.2.1 (GA) is a bug fix release that addresses a number of issues reported since release 4.2. Users of HttpClient 4.2 are advised to upgrade. Changelog ------------------- * [HTTPCLIENT-1209] Redirect URIs are now normalized. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1202] ResponseCachingPolicy should honor explicit cache-control directives for other status codes Contributed by Jon Moore * [HTTPCLIENT-1199] DecompressingHttpClient strips content from entity enclosing requests Contributed by Oleg Kalnichevski * [HTTPCLIENT-1198] HttpHost is not set in HttpContext in CachingHttpClient. Contributed by Jon Moore * [HTTPCLIENT-1200] DecompressingHttpClient fails to generate correct HttpHost context attribute. Contributed by Guillaume Castagnino * [HTTPCLIENT-1192] URIBuilder encodes query parameters twice. Contributed by Oleg Kalnichevski and Sebastian Bazley . * [HTTPCLIENT-1196] Fixed NPE in UrlEncodedFormEntity constructor thrown if charset is null. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1193] Fixed regression in the route tracking logic of the default connection manager causing cross-site redirect failures. Contributed by Oleg Kalnichevski Release 4.2 ------------------- This is the first stable (GA) release of HttpClient 4.2. The most notable enhancements included in this release are: * New facade API for HttpClient based on the concept of a fluent interface. The fluent API exposes only the most fundamental functions of HttpClient and is intended for relatively simple use cases that do not require the full flexibility of HttpClient. However, the fluent API almost fully relieves the users from having to deal with connection management and resource deallocation. * Redesigned and rewritten connection management code. * Enhanced HTTP authentication API that enables HttpClient to handle more complex authentication scenarios. HttpClient 4.2 is now capable of making use of multiple authentication challenges and retry authentication with a fall-back scheme in case the primary one fails. This can be important for compatibility with Microsoft products that are often configured to use SPNEGO/Kerberos as the preferred authentication scheme. Changelog ------------------- * [HTTPCLIENT-1187] If a revalidation response is deemed too old CachingHttpClient fails to consume its content resulting in a connection leak. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1186] State of newly created connections in the connection pool is not always correctly updated potentially allowing those connections to be leased to users with a different security context. Contributed by Ralf Poehlmann * [HTTPCLIENT-1179] Upgraded Commons Codec dependency to version 1.6 Contributed by Oleg Kalnichevski * [HTTPCLIENT-1177] always remove fragments from request URIs Contributed by Oleg Kalnichevski Incompatible changes -------------------- [Compared to release version 4.1.3] The following fields have been deprecated for some time now and have been deleted: org.apache.http.client.params.ClientPNames#CONNECTION_MANAGER_FACTORY org.apache.http.impl.cookie.BrowserCompatSpec#DATE_PATTERNS The following methods have been deprecated for some time now and have been deleted: org.apache.http.client.params.ClientParamBean#setConnectionManagerFactory(org.apache.http.conn.ClientConnectionManagerFactory) org.apache.http.client.protocol.ClientContextConfigurer#setAuthSchemePref(java.util.List) org.apache.http.entity.mime.content.FileBody#writeTo(java.io.OutputStream, int) org.apache.http.entity.mime.content.InputStreamBody#writeTo(java.io.OutputStream, int) org.apache.http.entity.mime.content.StringBody#writeTo(java.io.OutputStream, int) The following classes have been deprecated for some while now and have been deleted: org.apache.http.impl.conn.tsccm.RefQueueHandler org.apache.http.impl.conn.tsccm.AbstractConnPool no longer implements interface org.apache.http.impl.conn.tsccm.RefQueueHandler org.apache.http.impl.conn.tsccm.ConnPoolByRoute no longer implements interface org.apache.http.impl.conn.tsccm.RefQueueHandler org.apache.http.impl.conn.tsccm.RefQueueWorker Release 4.2 BETA1 ------------------- This is the first BETA release of HttpClient 4.2. This release completes development of several notable enhancements in HttpClient: * New facade API for HttpClient based on the concept of a fluent interface. The fluent API exposes only the most fundamental functions of HttpClient and is intended for relatively simple use cases that do not require the full flexibility of HttpClient. However, the fluent API almost fully relieves the users from having to deal with connection management and resource deallocation. * Redesigned and rewritten connection management code. As of release 4.2 HttpClient will be using pooling connection manager per default. * Enhanced HTTP authentication API that enables HttpClient to handle more complex authentication scenarios. HttpClient 4.2 is now capable of making use of multiple authentication challenges and retry authentication with a fall-back scheme in case the primary one fails. This can be important for compatibility with Microsoft products that are often configured to use SPNEGO/Kerberos as the preferred authentication scheme. Changelog ------------------- * [HTTPCLIENT-1164] Compressed entities are not being cached properly. Contributed by Jon Moore . * [HTTPCLIENT-1154] MemcachedHttpCacheStorage should allow client to specify custom prefix string for keys. Contributed by Jon Moore . * [HTTPCLIENT-1153] MemcachedHttpCacheStorage uses URL as cache key; shouldn't due to fixed maximum-length memcached keys. Contributed by Jon Moore . * [HTTPCLIENT-1157] MemcachedHttpCacheStroage should throw IOExceptions instead of RuntimeExceptions. Contributed by James Miller . * [HTTPCLIENT-1152] MemcachedHttpCacheStorage should verify class of returned object before casting. Contributed by Rajika Kumarasiri . * [HTTPCLIENT-1155] CachingHttpClient fails to ensure that the response content gets fully consumed when using a ResponseHandler, which can potentially lead to connection leaks. Contributed by James Miller * [HTTPCLIENT-1147] When HttpClient-Cache cannot open cache file, should act like miss. Contributed by Joe Campbell * [HTTPCLIENT-1137] Values for the Via header are cached and reused by httpclient-cache. Contributed by Alin Vasile * [HTTPCLIENT-1142] Infinite loop on NTLM authentication failure. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1143] CachingHttpClient leaks connections with stale-if-error. Contributed by James Miller Release 4.2 ALPHA1 ------------------- This is the first ALPHA release of HttpClient 4.2. The 4.2 branch enhances HttpClient in several key areas and includes several notable features and improvements: * New facade API for HttpClient based on the concept of a fluent interface. The fluent API exposes only the most fundamental functions of HttpClient and is intended for relatively simple use cases that do not require the full flexibility of HttpClient. However, the fluent API almost fully relieves the users from having to deal with connection management and resource deallocation. * Redesigned and rewritten connection management code. As of release 4.2 HttpClient will be using pooling connection manager per default. * Enhanced HTTP authentication API that enables HttpClient to handle more complex authentication scenarios. HttpClient 4.2 is now capable of making use of multiple authentication challenges and retry authentication with a fall-back scheme in case the primary one fails. This can be important for compatibility with Microsoft products that are often configured to use SPNEGO/Kerberos as the preferred authentication scheme. Please note that new features included in this release are still considered experimental and their API may change in the future ALPHA releases. Changelog ------------------- * [HTTPCLIENT-1128] SystemDefaultHttpClient (HttpClient implementation initialized using system properties). Contributed by Oleg Kalnichevski * [HTTPCLIENT-1135] RandomAccessFile mode 'w' used by HttpClientCache is not valid. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1131] HttpClient to authenticate preemptively using BASIC scheme if a userinfo attribute is specified in the request URI. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1134] make BasicResponseHandler consume response content in case of an unsuccessful result (status code >= 300). Contributed by Oleg Kalnichevski * [HTTPCLIENT-1132] ProxyClient implementation. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1127] fixed dead-lock between SingleClientConnManager and AbstractPooledConnAdapter. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1107] Auth framework redesign. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1116] ResponseCachingPolicy uses integers for sizes Contributed by Greg Bowyer * [HTTPCLIENT-1123] Support for pluggable DNS resolvers. Contributed by Alin Vasile * [HTTPCLIENT-1120] DefaultHttpRequestRetryHandler#retryRequest should not retry aborted requests. Contributed by Alin Vasile * Support for auth-int qop (quality of protection) option in Digest auth scheme. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1076] Fluent facade API (Google summer of code 2011 project). Contributed by Xu Lilu * UriBuilder implementation. Contributed by Xu Lilu * Redesign of connection management classes based on new pooling components from HttpCore. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1111] Added #prepareSocket method to SSLSocketFactory. Contributed by Pasi Eronen * Added #reset() and #releaseConnection() methods to HttpRequestBase. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1105] AutoRetryHttpClient: built-in way to do auto-retry for certain status codes. Contributed by Dan Checkoway * [HTTPCLIENT-1094] Digest auth scheme refactoring. Contributed by Oleg Kalnichevski * Lax implementation of RedirectStrategy. Contributed by Bartosz Firyn * [HTTPCLIENT-1044] HttpRequestRetryHandler implementation compliant with the definition of idempotent methods given in the RFC 2616. Contributed by Oleg Kalnichevski Release 4.1.2 ------------------- The HttpClient 4.1.2 is a bug fix release that addresses a number of non-critical issues reported since release 4.1.1. * [HTTPCLIENT-1100] Missing Content-Length header makes cached entry invalid Contributed by Bart Robeyns * [HTTPCLIENT-1098] Avoid expensive reverse DNS lookup on connect timeout exception. Contributed by Thomas Boettcher * [HTTPCLIENT-1097] BrowserCompatHostnameVerifier and StrictHostnameVerifier should handle wildcards in SSL certificates better. Contributed by Sebastian Bazley * [HTTPCLIENT-1092] If ClientPNames.VIRTUAL_HOST does not provide the port, derive it from the current request. Contributed by Sebastian Bazley * [HTTPCLIENT-1087] NTLM proxy authentication fails on retry if the underlying connection is closed as a result of a target authentication failure. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1079] Fixed Kerberos cross-realm support Contributed by Michael Osipov <1983-01-06 at gmx.net> * [HTTPCLIENT-1078] Decompressing entities (DeflateDecompressingEntity, GzipDecompressingEntity) do not close content stream in #writeTo() method. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1075] Decompressing entities (DeflateDecompressingEntity, GzipDecompressingEntity) do not correctly handle content streaming. Contributed by James Abley * [HTTPCLIENT-1051] Avoid reverse DNS lookups when opening SSL connections by IP address. Contributed by Oleg Kalnichevski Release 4.1.1 ------------------- HttpClient v4.1.1 is a bug fix release that addresses a number of issues reported since release 4.1, including one critical security issue (HTTPCLIENT-1061). All users of HttpClient 4.0.x and 4.1 are strongly encouraged to upgrade. * [HTTPCLIENT-1069] HttpHostConnectException not correctly retried for direct and non-tunnelled proxy connections. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1066] Changed the way URIUtils#rewriteURI handles multiple consecutive slashes in the URI path component: multiple leading slashes will be replaced by one slash in order to avoid confusion with the authority component. The remaining content of the path will not be modified. (also see HTTPCLIENT-929). Contributed by Oleg Kalnichevski * [HTTPCLIENT-1061] Fixed critical bug causing Proxy-Authorization header to be sent to the target host when tunneling requests through a proxy server that requires authentication. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1056] Fixed bug causing the RequestAuthCache protocol interceptor to generate an invalid AuthScope instance when looking up user credentials for preemptive authentication. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1053] Fixed the way DigestScheme generates nonce-count values. Contributed by Oleg Kalnichevski Release 4.1 ------------------- The HttpClient 4.1 release builds upon the stable foundation laid by HttpClient 4.0 and adds several functional improvements and popular features. * Response caching conditionally compliant with HTTP/1.1 specification (full compliance with MUST requirements, partial compliance with SHOULD requirements) * Full support for NTLMv1, NTLMv2, and NTLM2 Session authentication. The NTLM protocol code was kindly contributed by the Lucene Connector Framework project. * Support for SPNEGO/Kerberos authentication. * Persistence of authentication data between request executions within the same execution context. * Support for preemptive authentication for BASIC and DIGEST schemes. * Support for transparent content encoding. Please note transparent content encoding is not enabled per default in order to avoid conflicts with already existing custom content encoding solutions. * Mechanism to bypass the standard certificate trust verification (useful when dealing with self-signed certificates). * Simplified configuration for connection managers. * Transparent support for host multihoming. IMPORTANT: please note that the HttpClient 3.x branch is now officially END OF LIFE and is no longer maintained and supported by the Apache HttpComponents project. Changelog ------------------- * The public API for the caching module had a minor change between 4.1-beta and 4.1-GA to the HttpCacheEntry class - the deprecated public Set getVariantURIs() method and constructor public HttpCacheEntry(Date requestDate, Date responseDate, StatusLine statusLine, Header[] responseHeaders, Resource resource, Set variants) were both removed. This will not affect you unless you are implementing new storage backends that use the deprecated code and/or are implementing custom serializers for cache entries. * Changed Browser-Compatibility and Best-Match cookie policies to emulate the behaviour of FireFox more closely when parsing Netscape style cookies. Comma will no longer be treated as a header element separator if Set-Cookie does not contain a Version attribute mandated by the RFC2109 / RFC 2965 cookie specifications. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1036] StringBody has incorrect default for characterset. (Default changed to US-ASCII) Contributed by Sebastian Bazley * [HTTPCLIENT-975] Support stale-if-error and stale-while-revalidate extension directive (RFC5861). Contributed by Mohammed Azeem Uddin , Michajlo Matijkiw , and Matthew Hawthorne . * [HTTPCLIENT-1033] HttpRoute.equals(Object o) is quite inefficient, as it does not take full advantage of shortcut logic. Contributed by Sebastian Bazley * [HTTPCLIENT-1030] Implement "ignoreCookies" CookieSpec Contributed by Sebastian Bazley Release 4.1 BETA1 ------------------- HttpClient 4.1 BETA1 finalizes the 4.1 API and brings a number of major improvements to the HTTP caching module. This release also adds full support for NTLMv1, NTLMv2, and NTLM2 Session authentication. The NTLM protocol code was kindly contributed by the Lucene Connector Framework project. Changelog ------------------- * [HTTPCLIENT-1015] Support only-if-cached directive. Contributed by Michajlo Matijkiw * [HTTPCLIENT-990] Allow heuristic freshness caching. Contributed by Michajlo Matijkiw * [HTTPCLIENT-919] Support for NTLMv1, NTLMv2, and NTLM2 Session authentication. Contributed by Karl Wright * [HTTPCLIENT-1008] Send all variants' ETags on "variant miss". Contributed by Michajlo Matijkiw and Mohammed Azeem Uddin * [HTTPCLIENT-1011] Handling of IOExceptions thrown by cache components. Contributed by Jonathan Moore * [HTTPCLIENT-1003] Handle conditional requests in cache. Contributed by Michajlo Matijkiw and Mohammed Azeem Uddin * [HTTPCLIENT-1002] Stale connection check fails if wire logging is on. Contributed by Oleg Kalnichevski * [HTTPCLIENT-1000] Maximum connection lifetimes settings for ThreadSafeClientConnManager. Contributed by Michajlo Matijkiw * [HTTPCLIENT-960] HttpMultipart doesn't generate Content-Type header for binary parts in BROWSER_COMPATIBLE mode. Contributed by Oleg Kalnichevski * [HTTPCLIENT-998] Cache should use both Last-Modified and ETag for validations when available. Contributed by Jonathan Moore * [HTTPCLIENT-997] Cache module should handle out-of-order validations properly and unconditionally refresh. Contributed by Jonathan Moore * [HTTPCLIENT-994] Cache does not allow client to override origin-specified freshness using max-stale. Contributed by Jonathan Moore * [HTTPCLIENT-995] Cache returns cached responses even if validators not consistent with all conditional headers. Contributed by Jonathan Moore * [HTTPCLIENT-977] Memcached implementation for HttpCache. Contributed by Mohammed Azeem Uddin * [HTTPCLIENT-992] cache should not generate stale responses to requests explicitly requesting first-hand or fresh ones. Contributed by Jonathan Moore * [HTTPCLIENT-991] cache module produces improperly formatted Warning header when revalidation fails. Contributed by Jonathan Moore * [HTTPCLIENT-989] DefaultHttpRequestRetryHandler no longer retries non-idempotent http methods if NoHttpResponseException is thrown. Contributed by Oleg Kalnichevski * [HTTPCLIENT-988] Cache module should strip 'Content-Encoding: identity' from responses Contributed by Jonathan Moore * [HTTPCLIENT-987] cache module does not recognize equivalent URIs. Contributed by Jonathan Moore * [HTTPCLIENT-986] cache module does not completely handle upstream Warning headers correctly Contributed by Jonathan Moore * [HTTPCLIENT-985] cache module should populate Via header to capture upstream and downstream protocols Contributed by Jonathan Moore * [HTTPCLIENT-984] Additional conditional compliance tests for the caching module for Content-Encoding, Content-Location, Date, Expires, Server, Transfer-Encoding, and Vary headers. Contributed by Jonathan Moore * [HTTPCLIENT-978] HTTP cache update exception handling Contributed by Michajlo Matijkiw * [HTTPCLIENT-981] CachingHttpClient returns a 411 respones when executing a POST (HttpPost) request. Contributed by Joe Campbell * [HTTPCLIENT-980] CachingHttpClient returns a 503 response when the backend HttpClient produces an IOException. Contributed by Jonathan Moore * [HTTPCLIENT-978] Ehcache based HTTP cache implementation Contributed by Michajlo Matijkiw * [HTTPCLIENT-967] support for non-shared (private) caches Contributed by Jonathan Moore * [HTTPCLIENT-969] BasicCookieStore#getCookies() to return a copy of Cookie list Contributed by David Smiley * [HTTPCLIENT-965] Fixed problem with cache not honoring must-revalidate or proxy-revalidate Cache-Control directives. Contributed by Jonathan Moore * [HTTPCLIENT-964] 'no-cache' directives with field names are no longer transmitted downstream. Contributed by Jonathan Moore * [HTTPCLIENT-963] Fixed handling of 'Cache-Control: no-store' on requests. Contributed by Jonathan Moore * [HTTPCLIENT-962] Fixed handling of Authorization headers in shared cache mode. Contributed by Jonathan Moore * [HTTPCLIENT-961] Not all applicable URIs are invalidated on PUT/POST/DELETEs that pass through client cache. Contributed by Jonathan Moore * [HTTPCLIENT-958] Client cache no longer allows incomplete responses to be passed on to the client. Contributed by Jonathan Moore * [HTTPCLIENT-951] Non-repeatable entity enclosing requests are not correctly retried when 'expect-continue' handshake is active. Contributed by Oleg Kalnichevski * [HTTPCLIENT-948] In rare circumstances the idle connection handling code can leave closed connections in a inconsistent state. Contributed by Oleg Kalnichevski * [HTTPCLIENT-953] IllegalStateException thrown by RouteSpecificPool. Contributed by Guillaume * [HTTPCLIENT-952] Trust store parameter is ignored by SSLSocketFactory (affects version 4.1-alpha2 only) Contributed by Oleg Kalnichevski * [HTTPCLIENT-937] CacheEntry made immutable; now uses immutable HttpEntity to store cached content. Contributed by David Mays and Oleg Kalnichevski Release 4.1 ALPHA2 ------------------- HttpClient 4.1 ALPHA2 fixes a number of non-severe bugs discovered since the last release and introduces support for two frequently requested features: * HTTP/1.1 response caching * transparent support for host multihoming * a mechanism to bypass the standard certificate trust verification (useful when dealing with self-signed certificates) Compatibility notes ------------------- (1) Please note the HTTP caching module is still considered experimental and its API may change significantly in the future releases. (2) This release eliminates Mime4J as a dependency for the HttpMime module. HttpMime is no longer binary compatible with the previous releases. Full API and binary compatibility between minor versions of HttpMime will be maintained as of 4.1 GA release. Changelog ------------------- * [HTTPCLIENT-936] Fixed bug causing NPE or an infinite loop in the authentication code in case of a SPNEGO authentication failure. Contributed by Oleg Kalnichevski * [HTTPCLIENT-427] HTTP caching support Contributed by Joe Campbell, David Cleaver, David Mays, Jon Moore, Brad Spenla * Dropped dependency on Mime4j for HttpMime. Contributed by Oleg Kalnichevski * Extended SSLSocketFactory with a mechanism to bypass the standard certificate trust verification (primarily to simplify dealing with self-signed certificates) Contributed by Oleg Kalnichevski * [HTTPCLIENT-898] Improved support for host multihoming Contributed by Oleg Kalnichevski * [HTTPCLIENT-916] UsernamePasswordCredentials, NTUserPrincipal, BasicClientCookie, BasicClientCookie2 and BasicCookieStore made Serializable. Contributed by Oleg Kalnichevski * [HTTPCLIENT-914] Upgraded Commons Codec dependency to version 1.4 Contributed by Oleg Kalnichevski * [HTTPCLIENT-903] Use ConcurrentHashMap instead of [Linked]HashMap for thread-safety. Improve performance of AuthSchemeRegistry, CookieSpecRegistry and SchemeRegistry classes. Contributed by Sebastian Bazley * [HTTPCLIENT-902] HttpRequestRetryHandler not called on I/O exceptions thrown when opening a new connection. Contributed by Olivier Lamy and Oleg Kalnichevski Release 4.1 ALPHA1 ------------------- HttpClient 4.1 ALPHA1 builds on the stable 4.0 release and adds several functionality improvements and new features. * Simplified configuration of connection managers. * Persistence of authentication data between request executions within the same execution context. * Support for SPNEGO/Kerberos authentication scheme * Support for transparent content encoding. Please note transparent content encoding is not enabled per default in order to avoid conflicts with already existing custom content encoding solutions. * 5 to 10% performance increase due to elimination of unnecessary Log object lookups by short-lived components. Please note all methods and classes added in this release and marked as 4.1 are API unstable and can change in the future 4.1 ALPHA releases. Changelog ------------------- * [HTTPCLIENT-889] 'expect: continue' handshake disabled per default. Contributed by Oleg Kalnichevski * [HTTPCLIENT-862] Extended client's redirect handling interface to allow control of the content of the redirect. Contributed by Oleg Kalnichevski * [HTTPCLIENT-872] HttpClient can now persist authentication data between request executions as long as they share the same execution context. It has also become much easier to make HttpClient authenticate preemptively by pre-populating authentication data cache. Contributed by Oleg Kalnichevski * [HTTPCLIENT-883] SO_TIMEOUT is not reset on persistent (re-used) connections. Contributed by Oleg Kalnichevski * [HTTPCLIENT-832] Distinguish cookie format errors from violations of restrictions imposed by a cookie specification. In the latter case CookieRestrictionViolationException will be thrown. Contributed by Oleg Kalnichevski * [HTTPCLIENT-523] Support for SPNEGO authentication scheme. Contributed by Matthew Stevenson * Simplified configuration of connection managers. Total connection maximum and maximum connection per route limits can be set using methods of the class instead of HTTP parameters. Contributed by Oleg Kalnichevski * Added parameters to define the order of preference for supported auth schemes for target host and proxy authentication. Contributed by Oleg Kalnichevski * [HTTPCLIENT-875] DefaultClientConnectionOperator#openConnection doesn't update the connection state if the connection socket changed after the call to SocketFactory#connectSocket(). Contributed by Oleg Kalnichevski * [HTTPCLIENT-834] Transparent content encoding support. Contributed by James Abley Release 4.0.1 ------------------- This is a bug fix release that addresses a number of issues discovered since the previous stable release. None of the fixed bugs is considered critical. Most notably this release eliminates eliminates dependency on JCIP annotations. This release is also expected to improve performance by 5 to 10% due to elimination of unnecessary Log object lookups by short-lived components. Changelog ------------------- * [HTTPCLIENT-895] Eliminated Log lookups in short lived objects impairing performance. Contributed by Oleg Kalnichevski * [HTTPCLIENT-885] URLEncodedUtils now correctly parses form-url-encoded entities that specify a charset. Contributed by Oleg Kalnichevski * [HTTPCLIENT-884] UrlEncodedFormEntity now sets charset on the Content-Type header. Contributed by Jared Jacobs * [HTTPCLIENT-883] SO_TIMEOUT is not reset on persistent (re-used) connections. Contributed by Oleg Kalnichevski * [HTTPCLIENT-882] Auth state is now correctly updated if a successful NTLM authentication results in a redirect. This is a minor bug as HttpClient manages to recover from the problem automatically. Contributed by Oleg Kalnichevski * [HTTPCLIENT-881] Fixed race condition in AbstractClientConnAdapter that makes it possible for an aborted connection to be returned to the pool. Contributed by Tim Boemker and Oleg Kalnichevski * [HTTPCLIENT-866] Removed dependency on jcip-annotations.jar. Contributed by Oleg Kalnichevski and Sebastian Bazley Release 4.0 ------------------- HttpClient 4.0 represents a complete, ground-up redesign and almost a complete rewrite of the HttpClient 3.x codeline. This release finally addresses several design flaws that existed since the 1.0 release and could not be fixed without a major code overhaul and breaking API compatibility. Architectural changes --------------------- * Redesign of the HttpClient internals addressing all known major architectural shortcomings of the 3.x codeline. * Cleaner, more flexible and expressive API. * More modular structure. * Better performance and smaller memory footprint due to a more efficient HTTP transport based on HttpCore. * Implementation of cross-cutting HTTP protocol aspects through protocol interceptors. * Improved connection management, better handling of persistent connections, support for stateful connections * Pluggable redirect and authentication handlers. * Improved support for sending requests via a proxy or a chain of proxies * More flexible SSL context customization * Reduced intermediate garbage in the process of generating HTTP requests and parsing HTTP responses Important notes ------------------- * Future releases of HttpMime module may be binary incompatible with this release due to possible API changes in Apache Mime4J. Apache Mime4J is still being actively developed and its API is considered unstable. * HttpClient 4.0 is not fully binary compatible with 4.0 BETA1 release. Some protected variables in connection management class have been made final in order to help ensure their thread safety: org.apache.http.conn.BasicEofSensorWatcher#attemptReuse org.apache.http.conn.BasicEofSensorWatcher#managedConn org.apache.http.impl.conn.DefaultClientConnectionOperator#schemeRegistry org.apache.http.impl.conn.DefaultHttpRoutePlanner#schemeRegistry org.apache.http.impl.conn.ProxySelectorRoutePlanner#schemeRegistry org.apache.http.impl.conn.SingleClientConnManager#alwaysShutDown org.apache.http.impl.conn.SingleClientConnManager#connOperator org.apache.http.impl.conn.SingleClientConnManager#schemeRegistry org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager#connOperator org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager#schemeRegistry Bug fixes since 4.0 BETA2 release ------------------- * [HTTPCLIENT-861] URIUtils#resolve is now compatible with all examples given in RFC 3986. Contributed by Johannes Koch * [HTTPCLIENT-860] HttpClient no longer converts redirects of PUT/POST to GET for status codes 301, 302, 307, as required by the HTTP spec. Contributed by Oleg Kalnichevski * [HTTPCLIENT-859] CookieIdentityComparator now takes path attribute into consideration when comparing cookies. Contributed by Oleg Kalnichevski * HttpClient will no longer send expired cookies back to the origin server. Contributed by Oleg Kalnichevski * [HTTPCLIENT-856] Proxy NTLM authentication no longer fails on a redirect to a different host. Contributed by Oleg Kalnichevski * [HTTPCLIENT-841] Removed automatic connection release using garbage collection due to a memory leak. Contributed by Oleg Kalnichevski * [HTTPCLIENT-853] Fixed bug causing invalid cookie origin port to be selected when the target is accessed on the default port and the connection is established via a proxy. Contributed by Oleg Kalnichevski * [HTTPCLIENT-852] Fixed bug causing automatically retried redirects fail with CircularRedirectException. Contributed by Oleg Kalnichevski * Fixed problem with the default HTTP response parser failing to handle garbage preceding a valid HTTP response. Contributed by Oleg Kalnichevski * NonRepeatableRequestExceptions now include the cause that the original request failed. Contributed by Sam Berlin * [HTTPCLIENT-837] Fixed problem with the wire log skipping zero byte values if read one byte at a time. Contributed by Kirill Safonov * [HTTPCLIENT-823] 'http.conn-manager.max-total' parameter can be adjusted dynamically. However, the size of existing connection pools per route, once allocated, will not be adjusted. Contributed by Oleg Kalnichevski * [HTTPCLIENT-822] Default socket factories to rethrow SocketTimeoutException as ConnectTimeoutException in case of connect failure due to a time out. Contributed by Oleg Kalnichevski * [HTTPCLIENT-813] Fixed default port resolution. Invalid ports no longer get replaced with the default port value. Contributed by Oleg Kalnichevski Release 4.0 beta 2 ------------------- BETA2 is a maintenance release, which addresses a number of issues discovered since the previous release. The only significant new feature is an addition of an OSGi compliant bundle combining HttpClient and HttpMime jars. All upstream projects are strongly encouraged to upgrade. * Fixed NPE in DefaultRequestDirector thrown when retrying a failed request over a proxied connection. Contributed by Oleg Kalnichevski * [HTTPCLIENT-803] Fixed bug in SSL host verifier implementations causing the SSL certificate to be rejected as invalid if the connection is established using an IP address. Contributed by Oleg Kalnichevski * [HTTPCLIENT-806] DefaultHttpMethodRetryHandler will no longer retry on ConnectExceptions. Contributed by Oleg Kalnichevski * DigestScheme can use an arbitrary digest algorithm requested by the target server (such as SHA) as long as this algorithm is supported by the Java runtime. Contributed by Oleg Kalnichevski * Fixed parsing and validation of RFC2109 compliant Set-Cookie headers by the Best-Match cookie spec. Contributed by Oleg Kalnichevski * Fixed bug that can cause a managed connection to be returned from the pool in an inconsistent state. Contributed by Oleg Kalnichevski 4.0 Beta 1 ------------------- BETA1 release brings yet another round of API enhancements and improvements in the area of connection management. Among the most notable ones is the capability to handle stateful connections such as persistent NTLM connections and private key authenticated SSL connections. This is the first API stable release of HttpClient 4.0. All further releases in the 4.0 code line will maintain API compatibility with this release. There has been a number of important bug fixes since ALPHA4. All upstream projects are encouraged to upgrade to the latest release. Please note HttpClient currently provides only limited support for NTLM authentication. For details please see NTLM_SUPPORT.txt. ------------------- Changelog: ------------------- * [HTTPCLIENT-790] Protocol interceptors are now correctly invoked when executing CONNECT methods. Contributed by Oleg Kalnichevski * [HTTPCLIENT-668] Do not use static loggers. Contributed by Oleg Kalnichevski * [HTTPCLIENT-781] Respect Keep-Alive header's timeout value. Contributed by Sam Berlin * [HTTPCLIENT-779] Top-level classes (HttpClient, and HttpGet, HttpPut and similar HttpMethods) throw fewer checked exceptions. Contributed by Sam Berlin * HttpClient will throw an exception if an attempt is made to retry a request with a non-repeatable request entity. Contributed by Oleg Kalnichevski * Fixed request re-generation logic when retrying a failed request. Auto-generated headers will no accumulate. Contributed by Oleg Kalnichevski * [HTTPCLIENT-424] Preemptive authentication no longer limited to BASIC scheme only. HttpClient can be customized to authenticate preemptively with DIGEST scheme. Contributed by Oleg Kalnichevski * [HTTPCLIENT-670] Pluggable hostname resolver. Contributed by Oleg Kalnichevski * [HTTPCLIENT-719] Clone support for HTTP request and cookie objects. Contributed by Oleg Kalnichevski * [HTTPCLIENT-776] Fixed concurrency issues with AbstractPoolEntry. Contributed by Sam Berlin * Resolved a long standing problem with HttpClient not taking into account the user context when pooling / re-using connections. HttpClient now correctly handles stateful / user specific connections such as persistent NTLM connections and SSL connections with client side authentication. Contributed by Oleg Kalnichevski * [HTTPCLIENT-773] Improved handling of the 'expires' attribute by the 'Best Match' cookie spec. Contributed by Oleg Kalnichevski * Partial NTLM support (requires an external NTLM engine). For details see NTLM_SUPPORT.txt Contributed by Oleg Kalnichevski * Redesigned local execution context management. Contributed by Oleg Kalnichevski -------------------------------------- Release 4.0 Alpha 4 ------------------- ALPHA4 marks the completion of the overhaul of the connection management code in HttpClient. All known shortcomings of the old HttpClient 3.x connection management API have been addressed. NTLM authentication remains the only missing major feature in the new codeline that prevents us from moving awards the API freeze. There has been a number of important bug fixes since ALPHA3. All upstream projects are encouraged to upgrade to the latest release. ------------------- HttpClient 3.x features that have NOT yet been ported: ------------------- * NTLM authentication scheme ------------------- Changelog: ------------------- * [HTTPCLIENT-765] String.toLowerCase() / toUpperCase() should specify Locale.ENGLISH Contributed by Sebastian Bazley * [HTTPCLIENT-769] Do not pool connection marked non-reusable. Contributed by Oleg Kalnichevski * [HTTPCLIENT-763] Fixed problem with AbstractClientConnAdapter#abortConnection() not releasing the connection if called from the main execution thread while there is no blocking I/O operation. Contributed by Oleg Kalnichevski * [HTTPCLIENT-652] Added optional state attribute to managed client connections. This enables connection managers to correctly handle stateful connections. Contributed by Oleg Kalnichevski * [HTTPCLIENT-673] Revised max connections per route configuration Contributed by Oleg Kalnichevski * [HTTPCLIENT-753] Class Scheme and related classes moved to a separate package Contributed by Oleg Kalnichevski * [HTTPCLIENT-757] Improved request wrapping in the DefaultClientRequestDirector. This also fixed the problem with the default proxy set at the client level having no effect. Contributed by Oleg Kalnichevski * [HTTPCLIENT-734] Request abort will unblock the thread waiting for a connection Contributed by Sam Berlin * [HTTPCLIENT-759] Ensure release of connections back to the connection manager on exceptions. Contributed by Sam Berlin * [HTTPCLIENT-758] Fixed the use of generics in AbstractHttpClient #removeRequestInterceptorByClass and #removeResponseInterceptorByClass Contributed by Johannes Koch * [HTTPCLIENT-749] HttpParams beans Contributed by Stojce Dimski * [HTTPCLIENT-755] Workaround for known bugs in java.net.URI.resolve() Bug ID: 4708535 Contributed by Johannes Koch -------------------------------------- Release 4.0 Alpha 3 ------------------- ALPHA3 release brings another round of API refinements and improvements in functionality. As of this release HttpClient requires Java 5 compatible runtime environment and takes full advantage of generics and new concurrency primitives. This release also introduces new default cookie policy that selects a cookie specification depending on the format of cookies sent by the target host. It is no longer necessary to know beforehand what kind of HTTP cookie support the target host provides. HttpClient is now able to pick up either a lenient or a strict cookie policy depending on the compliance level of the target host. Another notable improvement is a completely reworked support for multipart entities based on Apache mime4j library. ------------------- HttpClient 3.x features that have NOT yet been ported: ------------------- * NTLM authentication scheme ------------------- Changelog: ------------------- * [HTTPCLIENT-742] common interface for HttpRoute and RouteTracker Contributed by Roland Weber * [HTTPCLIENT-741] Fixed concurrency issues in AbstractClientConnAdapter. Contributed by Oleg Kalnichevski * [HTTPCLIENT-726] testcase for spurious wakeups in ThreadSafeClientConnManager Contributed by Roland Weber * [HTTPCLIENT-643] Automatic connect fail-over for multi-home remote servers. Contributed by Oleg Kalnichevski * [HTTPCLIENT-735] unsetting of DEFAULT_PROXY and FORCED_ROUTE in hierarchies Contributed by Roland Weber * [HTTPCLIENT-723] route planner based on java.net.ProxySelector Contributed by Roland Weber * [HTTPCLIENT-740] don't start connection GC thread in pool constructor Contributed by Roland Weber * [HTTPCLIENT-736] route planners use SchemeRegistry instead of ConnManager Contributed by Roland Weber * [HTTPCLIENT-730] Fixed rewriting of URIs containing escaped characters Contributed by Sam Berlin and Oleg Kalnichevski * [HTTPCLIENT-667] Added 'Meta' cookie policy that selects a cookie specification depending on the format of the cookie(s). Contributed by Oleg Kalnichevski * [HTTPCLIENT-729] Move HttpRoute and related classes to routing package. Contributed by Roland Weber * [HTTPCLIENT-725] Use TimeUnit arguments for timeouts in connection manager. Contributed by Roland Weber * [HTTPCLIENT-677] Connection manager no longer uses Thread.interrupt(). Contributed by Roland Weber * [HTTPCLIENT-716] Allow application-defined routes. Contributed by Roland Weber * [HTTPCLIENT-712] Improve HttpRoute API Contributed by Roland Weber * [HTTPCLIENT-711] Bad route computed for redirected requests Contributed by Oleg Kalnichevski * [HTTPCLIENT-715] Remove RoutedRequest from API Contributed by Roland Weber * [HTTPCLIENT-705] Fixed incorrect handling of URIs with null path component. Contributed by Oleg Kalnichevski * [HTTPCLIENT-688] HttpOptions#getAllowedMethods can now handle multiple Allow headers. Contributed by Andrea Selva -------------------------------------- Release 4.0 Alpha 2 ------------------- ALPHA2 release is another milestone in the redesign of HttpClient. It includes a number of improvements since ALPHA1, among which are improved connection pooling, support for proxy chains, redesigned HTTP state and authentication credentials management API, improved RFC 2965 cookie specification. ------------------- HttpClient 3.x features that have NOT yet been ported ------------------- * NTLM authentication scheme * Support for multipart MIME coded entities ------------------- Changelog ------------------- * [HTTPCLIENT-698] Resolve non-absolute redirect URIs relative to the request URI Contributed by Johannes Koch * [HTTPCLIENT-697] Throw a more intelligible exception when connection to a remote host cannot be established. Contributed by Oleg Kalnichevski * [HTTPCLIENT-689] Caching of SimpleDateFormat in DateUtils Contributed by Daniel Müller * [HTTPCLIENT-689] stackable parameters in AbstractHttpClient Contributed by Roland Weber * [HTTPCLIENT-477] Use distinct instances of the authentication handler interface for authentication with target and proxy hosts Contributed by Oleg Kalnichevski * [HTTPCLIENT-690] ManagedClientConnection provides access to SSLSession Contributed by Roland Weber * [HTTPCLIENT-692] ClientConnectionManager throws InterruptedException Contributed by Roland Weber * [HTTPCORE-116] moved parameter names to interfaces Contributed by Roland Weber * [HTTPCLIENT-649] support for proxy chains in HttpConn Contributed by Roland Weber * [HTTPCLIENT-636] refactor ThreadSafeClientConnManager in separate package Contributed by Roland Weber * [HTTPCLIENT-669] new HttpRoutePlanner interface and implementation Contributed by Andrea Selva * [HTTPCLIENT-653] detached connection wrapper no longer prevents garbage collection of ThreadSafeClientConnManager Contributed by Roland Weber * [HTTPCLIENT-674] use org.apache.http.util.VersionInfo instead of a local one Contributed by Roland Weber * [HTTPCLIENT-666] Replaced HttpState with CredentialsProvier and CookieStore interfaces Contributed by Oleg Kalnichevski * [HTTPCORE-100] revised HttpContext hierarchy Contributed by Roland Weber * [HTTPCLIENT-618] eliminate class HostConfiguration Contributed by Roland Weber * [HTTPCLIENT-672] re-sync with API changes in core alpha6-SNAPSHOT Contributed by Roland Weber -------------------------------------- Release 4.0 Alpha 1 ------------------- HttpClient 4.0 represents a complete, ground-up redesign and almost a complete rewrite of the HttpClient 3.x codeline. This release finally addresses several design flaws that existed since the 1.0 release and could not be fixed without a major code overhaul and breaking API compatibility. The HttpClient 4.0 API is still very experimental and is bound to change during the course of the ALPHA development phase. Several important features have not yet been ported to the new API. Architectural changes --------------------- * Redesign of the HttpClient internals addressing all known major architectural shortcomings of the 3.x codeline * Cleaner, more flexible and expressive API * Better performance and smaller memory footprint due to a more efficient HTTP transport based on HttpCore. HttpClient 4.0 is expected to be 10% to 25% faster than HttpClient 3.x codeline * More modular structure * Pluggable redirect and authentication handlers * Support for protocol incerceptors * Improved connection management * Improved support for sending requests via a proxy or a chain of proxies * Improved handling redirects of entity enclosing requests * More flexible SSL context customization * Reduced intermediate garbage in the process of generating HTTP requests and parsing HTTP responses ------------------- HttpClient 3.x features that have NOT yet been ported ------------------- * NTLM authentication scheme * RFC2965 cookie policy (Cookie2) * Support for multipart MIME coded entities ------------------- Changelog ------------------- The following is a list of contributions tracked in JIRA. Note that this is not a complete list of contributions or changes. Since the API was redesigned completely, tracking everything outside of the source code repository would have been too burdensome. * [HTTPCLIENT-655] User-Agent string no longer violates RFC Contributed by Oleg Kalnichevski * [HTTPCLIENT-541] Virtual host API redesign Contributed by Oleg Kalnichevski * [HTTPCLIENT-614] Allow for different strategies when checking CN of x509 certificates Contributed by Julius Davies * [HTTPCLIENT-136] Fixed inadequate proxy support Long standing architectural problem. Issue opened on 19/Dec/2002. Contributed by Oleg Kalnichevski * [HTTPCLIENT-63] Support for pluggable redirect and authentication handlers Long standing architectural problem. Issue opened on 15/Jul/2002. Contributed by Oleg Kalnichevski * [HTTPCLIENT-245] Fixed redirect handling. HttpClient can now automatically handle redirects of entity enclosing requests. Long standing architectural problem. Issue opened on 14/Jul/2003. Contributed by Oleg Kalnichevski * [HTTPCLIENT-613] HTTPS connections now verify CN of x509 certificates Contributed by Julius Davies * [HTTPCLIENT-497] Wire/header logger names consistent with class loggers Contributed by Oleg Kalnichevski * [HTTPCLIENT-484] AuthSSLProtocolSocketFactory in the main distribution Contributed by Oleg Kalnichevski * [HTTPCLIENT-589] Do not consume the remaining response content if the connection is to be closed Contributed by Roland Weber * [HTTPCLIENT-475] Support for unconnected sockets. HTTP requests can now be aborted while network socket is still being connected. Contributed by Roland Weber httpcomponents-client-4.3.3/fluent-hc/0040755 0000000 0000000 00000000000 12301752743 016505 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/pom.xml0100644 0000000 0000000 00000011155 12301751737 020024 0ustar000000000 0000000 4.0.0 org.apache.httpcomponents httpcomponents-client 4.3.3 fluent-hc Fluent API for Apache HttpClient 2011 HttpComponents Client fluent API http://hc.apache.org/httpcomponents-client jar org.apache.httpcomponents httpclient ${project.version} compile org.apache.httpcomponents httpclient ${project.version} test tests commons-logging commons-logging junit junit test org.mockito mockito-core test src/main/resources true **/*.properties maven-javadoc-plugin ${hc.javadoc.version} true ${maven.compiler.source} http://download.oracle.com/javase/1.5.0/docs/api/ http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/ http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/ javadoc maven-project-info-reports-plugin ${hc.project-info.version} false dependencies dependency-info summary maven-jxr-plugin ${hc.jxr.version} maven-surefire-report-plugin ${hc.surefire-report.version} httpcomponents-client-4.3.3/fluent-hc/src/0040755 0000000 0000000 00000000000 12301751740 017270 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/examples/0040755 0000000 0000000 00000000000 12301751734 021111 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/examples/org/0040755 0000000 0000000 00000000000 12301751734 021700 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/examples/org/apache/0040755 0000000 0000000 00000000000 12301751734 023121 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/examples/org/apache/http/0040755 0000000 0000000 00000000000 12301751735 024101 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/examples/org/apache/http/client/0040755 0000000 0000000 00000000000 12301751736 025360 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/examples/org/apache/http/client/fluent/0040755 0000000 0000000 00000000000 12301751737 026656 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/examples/org/apache/http/client/fluent/FluentAsync.java0100644 0000000 0000000 00000006110 12301751737 031747 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.util.LinkedList; import java.util.Queue; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import org.apache.http.concurrent.FutureCallback; /** * This example demonstrates how the he HttpClient fluent API can be used to execute multiple * requests asynchronously using background threads. */ public class FluentAsync { public static void main(String[] args)throws Exception { // Use pool of two threads ExecutorService threadpool = Executors.newFixedThreadPool(2); Async async = Async.newInstance().use(threadpool); Request[] requests = new Request[] { Request.Get("http://www.google.com/"), Request.Get("http://www.yahoo.com/"), Request.Get("http://www.apache.com/"), Request.Get("http://www.apple.com/") }; Queue> queue = new LinkedList>(); // Execute requests asynchronously for (final Request request: requests) { Future future = async.execute(request, new FutureCallback() { public void failed(final Exception ex) { System.out.println(ex.getMessage() + ": " + request); } public void completed(final Content content) { System.out.println("Request completed: " + request); } public void cancelled() { } }); queue.add(future); } while(!queue.isEmpty()) { Future future = queue.remove(); try { future.get(); } catch (ExecutionException ex) { } } System.out.println("Done"); threadpool.shutdown(); } } ././@LongLink0100644 0000000 0000000 00000000145 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/examples/org/apache/http/client/fluent/FluentExecutor.javahttpcomponents-client-4.3.3/fluent-hc/src/examples/org/apache/http/client/fluent/FluentExecutor.java0100644 0000000 0000000 00000006300 12301751737 032471 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.io.File; import org.apache.http.HttpHost; import org.apache.http.HttpVersion; import org.apache.http.entity.ContentType; /** * This example demonstrates how the he HttpClient fluent API can be used to execute multiple * requests within the same security context. The Executor class maintains a common context shared * by all requests executed with it. The Executor is thread-safe and can be used to execute * requests concurrently from multiple threads of execution. */ public class FluentExecutor { public static void main(String[] args)throws Exception { Executor executor = Executor.newInstance() .auth(new HttpHost("somehost"), "username", "password") .auth(new HttpHost("myproxy", 8080), "username", "password") .authPreemptive(new HttpHost("myproxy", 8080)); // Execute a GET with timeout settings and return response content as String. executor.execute(Request.Get("http://somehost/") .connectTimeout(1000) .socketTimeout(1000) ).returnContent().asString(); // Execute a POST with the 'expect-continue' handshake, using HTTP/1.1, // containing a request body as String and return response content as byte array. executor.execute(Request.Post("http://somehost/do-stuff") .useExpectContinue() .version(HttpVersion.HTTP_1_1) .bodyString("Important stuff", ContentType.DEFAULT_TEXT) ).returnContent().asBytes(); // Execute a POST with a custom header through the proxy containing a request body // as an HTML form and save the result to the file executor.execute(Request.Post("http://somehost/some-form") .addHeader("X-Custom-header", "stuff") .viaProxy(new HttpHost("myproxy", 8080)) .bodyForm(Form.form().add("username", "vip").add("password", "secret").build()) ).saveContent(new File("result.dump")); } } ././@LongLink0100644 0000000 0000000 00000000147 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/examples/org/apache/http/client/fluent/FluentQuickStart.javahttpcomponents-client-4.3.3/fluent-hc/src/examples/org/apache/http/client/fluent/FluentQuickStart.ja0100644 0000000 0000000 00000003415 12301751737 032442 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; public class FluentQuickStart { public static void main(String[] args) throws Exception { // The fluent API relieves the user from having to deal with manual // deallocation of system resources at the cost of having to buffer // response content in memory in some cases. Request.Get("http://targethost/homepage") .execute().returnContent(); Request.Post("http://targethost/login") .bodyForm(Form.form().add("username", "vip").add("password", "secret").build()) .execute().returnContent(); } } ././@LongLink0100644 0000000 0000000 00000000145 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/examples/org/apache/http/client/fluent/FluentRequests.javahttpcomponents-client-4.3.3/fluent-hc/src/examples/org/apache/http/client/fluent/FluentRequests.java0100644 0000000 0000000 00000005236 12301751737 032515 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.io.File; import org.apache.http.HttpHost; import org.apache.http.HttpVersion; import org.apache.http.entity.ContentType; /** * This example demonstrates basics of request execution with the HttpClient fluent API. */ public class FluentRequests { public static void main(String[] args)throws Exception { // Execute a GET with timeout settings and return response content as String. Request.Get("http://somehost/") .connectTimeout(1000) .socketTimeout(1000) .execute().returnContent().asString(); // Execute a POST with the 'expect-continue' handshake, using HTTP/1.1, // containing a request body as String and return response content as byte array. Request.Post("http://somehost/do-stuff") .useExpectContinue() .version(HttpVersion.HTTP_1_1) .bodyString("Important stuff", ContentType.DEFAULT_TEXT) .execute().returnContent().asBytes(); // Execute a POST with a custom header through the proxy containing a request body // as an HTML form and save the result to the file Request.Post("http://somehost/some-form") .addHeader("X-Custom-header", "stuff") .viaProxy(new HttpHost("myproxy", 8080)) .bodyForm(Form.form().add("username", "vip").add("password", "secret").build()) .execute().saveContent(new File("result.dump")); } } ././@LongLink0100644 0000000 0000000 00000000155 12302131604 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/examples/org/apache/http/client/fluent/FluentResponseHandling.javahttpcomponents-client-4.3.3/fluent-hc/src/examples/org/apache/http/client/fluent/FluentResponseHandl0100644 0000000 0000000 00000007544 12301751737 032533 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.io.IOException; import java.nio.charset.Charset; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.http.Consts; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpResponseException; import org.apache.http.client.ResponseHandler; import org.apache.http.entity.ContentType; import org.w3c.dom.Document; import org.xml.sax.SAXException; /** * This example demonstrates how the HttpClient fluent API can be used to handle HTTP responses * without buffering content body in memory. */ public class FluentResponseHandling { public static void main(String[] args)throws Exception { Document result = Request.Get("http://somehost/content") .execute().handleResponse(new ResponseHandler() { public Document handleResponse(final HttpResponse response) throws IOException { StatusLine statusLine = response.getStatusLine(); HttpEntity entity = response.getEntity(); if (statusLine.getStatusCode() >= 300) { throw new HttpResponseException( statusLine.getStatusCode(), statusLine.getReasonPhrase()); } if (entity == null) { throw new ClientProtocolException("Response contains no content"); } DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); try { DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); ContentType contentType = ContentType.getOrDefault(entity); if (!contentType.equals(ContentType.APPLICATION_XML)) { throw new ClientProtocolException("Unexpected content type:" + contentType); } Charset charset = contentType.getCharset(); if (charset == null) { charset = Consts.ISO_8859_1; } return docBuilder.parse(entity.getContent(), charset.name()); } catch (ParserConfigurationException ex) { throw new IllegalStateException(ex); } catch (SAXException ex) { throw new ClientProtocolException("Malformed XML document", ex); } } }); // Do something useful with the result System.out.println(result); } } httpcomponents-client-4.3.3/fluent-hc/src/main/0040755 0000000 0000000 00000000000 12301751740 020214 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/main/java/0040755 0000000 0000000 00000000000 12301751740 021135 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/0040755 0000000 0000000 00000000000 12301751740 021724 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/0040755 0000000 0000000 00000000000 12301751740 023145 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/0040755 0000000 0000000 00000000000 12301751740 024124 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/0040755 0000000 0000000 00000000000 12301751740 025402 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/0040755 0000000 0000000 00000000000 12301751741 026700 5ustar000000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/Async.java0100644 0000000 0000000 00000007641 12301751741 030625 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.util.concurrent.Future; import org.apache.http.client.ResponseHandler; import org.apache.http.concurrent.BasicFuture; import org.apache.http.concurrent.FutureCallback; public class Async { private Executor executor; private java.util.concurrent.Executor concurrentExec; public static Async newInstance() { return new Async(); } Async() { super(); } public Async use(final Executor executor) { this.executor = executor; return this; } public Async use(final java.util.concurrent.Executor concurrentExec) { this.concurrentExec = concurrentExec; return this; } static class ExecRunnable implements Runnable { private final BasicFuture future; private final Request request; private final Executor executor; private final ResponseHandler handler; ExecRunnable( final BasicFuture future, final Request request, final Executor executor, final ResponseHandler handler) { super(); this.future = future; this.request = request; this.executor = executor; this.handler = handler; } public void run() { try { final Response response = this.executor.execute(this.request); final T result = response.handleResponse(this.handler); this.future.completed(result); } catch (final Exception ex) { this.future.failed(ex); } } } public Future execute( final Request request, final ResponseHandler handler, final FutureCallback callback) { final BasicFuture future = new BasicFuture(callback); final ExecRunnable runnable = new ExecRunnable( future, request, this.executor != null ? this.executor : Executor.newInstance(), handler); if (this.concurrentExec != null) { this.concurrentExec.execute(runnable); } else { final Thread t = new Thread(runnable); t.setDaemon(true); t.start(); } return future; } public Future execute(final Request request, final ResponseHandler handler) { return execute(request, handler, null); } public Future execute(final Request request, final FutureCallback callback) { return execute(request, new ContentResponseHandler(), callback); } public Future execute(final Request request) { return execute(request, new ContentResponseHandler(), null); } } httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/Content.java0100644 0000000 0000000 00000004575 12301751741 031165 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import org.apache.http.Consts; import org.apache.http.entity.ContentType; public class Content { public static final Content NO_CONTENT = new Content(new byte[] {}, ContentType.DEFAULT_BINARY); private final byte[] raw; private final ContentType type; Content(final byte[] raw, final ContentType type) { super(); this.raw = raw; this.type = type; } public ContentType getType() { return this.type; } public byte[] asBytes() { return this.raw.clone(); } public String asString() { Charset charset = this.type.getCharset(); if (charset == null) { charset = Consts.ISO_8859_1; } try { return new String(this.raw, charset.name()); } catch (final UnsupportedEncodingException ex) { return new String(this.raw); } } public InputStream asStream() { return new ByteArrayInputStream(this.raw); } @Override public String toString() { return asString(); } } ././@LongLink0100644 0000000 0000000 00000000156 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/ContentResponseHandler.javahttpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/ContentResponseHan0100644 0000000 0000000 00000004414 12301751740 032402 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.io.IOException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpResponseException; import org.apache.http.client.ResponseHandler; import org.apache.http.entity.ContentType; import org.apache.http.util.EntityUtils; class ContentResponseHandler implements ResponseHandler { public Content handleResponse( final HttpResponse response) throws ClientProtocolException, IOException { final StatusLine statusLine = response.getStatusLine(); final HttpEntity entity = response.getEntity(); if (statusLine.getStatusCode() >= 300) { throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase()); } if (entity != null) { return new Content( EntityUtils.toByteArray(entity), ContentType.getOrDefault(entity)); } return Content.NO_CONTENT; } } httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/Executor.java0100644 0000000 0000000 00000020563 12301751741 031344 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.io.IOException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import javax.net.ssl.SSLContext; import org.apache.http.HttpHost; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.auth.NTCredentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthCache; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CookieStore; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.HttpClient; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.LayeredConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLInitializationException; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicHeader; /** * An Executor for fluent requests *

* A {@link PoolingHttpClientConnectionManager} with maximum 100 connections per route and * a total maximum of 200 connections is used internally. */ public class Executor { final static PoolingHttpClientConnectionManager CONNMGR; final static HttpClient CLIENT; static { LayeredConnectionSocketFactory ssl = null; try { ssl = SSLConnectionSocketFactory.getSystemSocketFactory(); } catch (final SSLInitializationException ex) { final SSLContext sslcontext; try { sslcontext = SSLContext.getInstance(SSLConnectionSocketFactory.TLS); sslcontext.init(null, null, null); ssl = new SSLConnectionSocketFactory(sslcontext); } catch (final SecurityException ignore) { } catch (final KeyManagementException ignore) { } catch (final NoSuchAlgorithmException ignore) { } } final Registry sfr = RegistryBuilder.create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", ssl != null ? ssl : SSLConnectionSocketFactory.getSocketFactory()) .build(); CONNMGR = new PoolingHttpClientConnectionManager(sfr); CONNMGR.setDefaultMaxPerRoute(100); CONNMGR.setMaxTotal(200); CLIENT = HttpClientBuilder.create().setConnectionManager(CONNMGR).build(); } public static Executor newInstance() { return new Executor(CLIENT); } public static Executor newInstance(final HttpClient httpclient) { return new Executor(httpclient != null ? httpclient : CLIENT); } private final HttpClient httpclient; private final AuthCache authCache; private final CredentialsProvider credentialsProvider; private volatile CookieStore cookieStore; Executor(final HttpClient httpclient) { super(); this.httpclient = httpclient; this.credentialsProvider = new BasicCredentialsProvider(); this.authCache = new BasicAuthCache(); } public Executor auth(final AuthScope authScope, final Credentials creds) { this.credentialsProvider.setCredentials(authScope, creds); return this; } public Executor auth(final HttpHost host, final Credentials creds) { final AuthScope authScope = host != null ? new AuthScope(host.getHostName(), host.getPort()) : AuthScope.ANY; return auth(authScope, creds); } public Executor authPreemptive(final HttpHost host) { final BasicScheme basicScheme = new BasicScheme(); try { basicScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "BASIC ")); } catch (final MalformedChallengeException ignore) { } this.authCache.put(host, basicScheme); return this; } public Executor authPreemptiveProxy(final HttpHost host) { final BasicScheme basicScheme = new BasicScheme(); try { basicScheme.processChallenge(new BasicHeader(AUTH.PROXY_AUTH, "BASIC ")); } catch (final MalformedChallengeException ignore) { } this.authCache.put(host, basicScheme); return this; } public Executor auth(final Credentials cred) { return auth(AuthScope.ANY, cred); } public Executor auth(final String username, final String password) { return auth(new UsernamePasswordCredentials(username, password)); } public Executor auth(final String username, final String password, final String workstation, final String domain) { return auth(new NTCredentials(username, password, workstation, domain)); } public Executor auth(final HttpHost host, final String username, final String password) { return auth(host, new UsernamePasswordCredentials(username, password)); } public Executor auth(final HttpHost host, final String username, final String password, final String workstation, final String domain) { return auth(host, new NTCredentials(username, password, workstation, domain)); } public Executor clearAuth() { this.credentialsProvider.clear(); return this; } public Executor cookieStore(final CookieStore cookieStore) { this.cookieStore = cookieStore; return this; } public Executor clearCookies() { this.cookieStore.clear(); return this; } /** * Executes the request. Please Note that response content must be processed * or discarded using {@link Response#discardContent()}, otherwise the * connection used for the request might not be released to the pool. * * @see Response#handleResponse(org.apache.http.client.ResponseHandler) * @see Response#discardContent() */ public Response execute( final Request request) throws ClientProtocolException, IOException { final HttpClientContext localContext = HttpClientContext.create(); localContext.setAttribute(HttpClientContext.CREDS_PROVIDER, this.credentialsProvider); localContext.setAttribute(HttpClientContext.AUTH_CACHE, this.authCache); localContext.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); final InternalHttpRequest httprequest = request.prepareRequest(); return new Response(this.httpclient.execute(httprequest, localContext)); } /** * @deprecated (4.3) do not use. */ @Deprecated public static void registerScheme(final org.apache.http.conn.scheme.Scheme scheme) { } /** * @deprecated (4.3) do not use. */ @Deprecated public static void unregisterScheme(final String name) { } } httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/Form.java0100644 0000000 0000000 00000003472 12301751741 030451 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.util.ArrayList; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; public class Form { private final List params; public static Form form() { return new Form(); } Form() { super(); this.params = new ArrayList(); } public Form add(final String name, final String value) { this.params.add(new BasicNameValuePair(name, value)); return this; } public List build() { return new ArrayList(this.params); } } httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/HttpHeader.java0100644 0000000 0000000 00000003141 12301751740 031566 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; class HttpHeader { public static final String CONTENT_LENGTH = "Content-Length"; public static final String DATE = "Date"; public static final String CACHE_CONTROL = "Cache-Control"; public static final String CONTENT_TYPE = "Content-Type"; public static final String IF_MODIFIED_SINCE = "If-Modified-Since"; public static final String IF_UNMODIFIED_SINCE = "If-Unmodified-Since"; } ././@LongLink0100644 0000000 0000000 00000000157 12302131604 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/InternalByteArrayEntity.javahttpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/InternalByteArrayE0100644 0000000 0000000 00000006302 12301751741 032325 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.http.entity.AbstractHttpEntity; import org.apache.http.entity.ContentType; import org.apache.http.util.Args; class InternalByteArrayEntity extends AbstractHttpEntity implements Cloneable { private final byte[] b; private final int off, len; public InternalByteArrayEntity(final byte[] b, final ContentType contentType) { super(); Args.notNull(b, "Source byte array"); this.b = b; this.off = 0; this.len = this.b.length; if (contentType != null) { setContentType(contentType.toString()); } } public InternalByteArrayEntity(final byte[] b, final int off, final int len, final ContentType contentType) { super(); Args.notNull(b, "Source byte array"); if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) < 0) || ((off + len) > b.length)) { throw new IndexOutOfBoundsException("off: " + off + " len: " + len + " b.length: " + b.length); } this.b = b; this.off = off; this.len = len; if (contentType != null) { setContentType(contentType.toString()); } } public InternalByteArrayEntity(final byte[] b) { this(b, null); } public InternalByteArrayEntity(final byte[] b, final int off, final int len) { this(b, off, len, null); } public boolean isRepeatable() { return true; } public long getContentLength() { return this.len; } public InputStream getContent() { return new ByteArrayInputStream(this.b, this.off, this.len); } public void writeTo(final OutputStream outstream) throws IOException { Args.notNull(outstream, "Output stream"); outstream.write(this.b, this.off, this.len); outstream.flush(); } public boolean isStreaming() { return false; } } ././@LongLink0100644 0000000 0000000 00000000152 12302131604 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/InternalFileEntity.javahttpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/InternalFileEntity0100644 0000000 0000000 00000005132 12301751741 032372 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.http.entity.AbstractHttpEntity; import org.apache.http.entity.ContentType; import org.apache.http.util.Args; class InternalFileEntity extends AbstractHttpEntity implements Cloneable { private final File file; public InternalFileEntity(final File file, final ContentType contentType) { super(); this.file = Args.notNull(file, "File"); if (contentType != null) { setContentType(contentType.toString()); } } public boolean isRepeatable() { return true; } public long getContentLength() { return this.file.length(); } public InputStream getContent() throws IOException { return new FileInputStream(this.file); } public void writeTo(final OutputStream outstream) throws IOException { Args.notNull(outstream, "Output stream"); final InputStream instream = new FileInputStream(this.file); try { final byte[] tmp = new byte[4096]; int l; while ((l = instream.read(tmp)) != -1) { outstream.write(tmp, 0, l); } outstream.flush(); } finally { instream.close(); } } public boolean isStreaming() { return false; } } ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/InternalHttpRequest.javahttpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/InternalHttpReques0100644 0000000 0000000 00000006606 12301751741 032431 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.net.URI; import org.apache.http.HttpVersion; import org.apache.http.ProtocolVersion; import org.apache.http.RequestLine; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.Configurable; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.message.AbstractHttpMessage; import org.apache.http.message.BasicRequestLine; import org.apache.http.util.Args; @NotThreadSafe class InternalHttpRequest extends AbstractHttpMessage implements HttpUriRequest, Configurable { private final String method; private ProtocolVersion version; private URI uri; private RequestConfig config; InternalHttpRequest(final String method, final URI requestURI) { Args.notBlank(method, "Method"); Args.notNull(requestURI, "Request URI"); this.method = method; this.uri = requestURI; } public void setProtocolVersion(final ProtocolVersion version) { this.version = version; } public ProtocolVersion getProtocolVersion() { return version != null ? version : HttpVersion.HTTP_1_1; } public String getMethod() { return this.method; } public URI getURI() { return this.uri; } public void abort() throws UnsupportedOperationException { } public boolean isAborted() { return false; } public RequestLine getRequestLine() { final String method = getMethod(); final ProtocolVersion ver = getProtocolVersion(); final URI uri = getURI(); String uritext = null; if (uri != null) { uritext = uri.toASCIIString(); } if (uritext == null || uritext.length() == 0) { uritext = "/"; } return new BasicRequestLine(method, uritext, ver); } public RequestConfig getConfig() { return config; } public void setConfig(final RequestConfig config) { this.config = config; } public void setURI(final URI uri) { this.uri = uri; } @Override public String toString() { return getMethod() + " " + getURI() + " " + getProtocolVersion(); } } ././@LongLink0100644 0000000 0000000 00000000161 12302131604 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/InternalInputStreamEntity.javahttpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/InternalInputStrea0100644 0000000 0000000 00000006147 12301751741 032423 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.http.entity.AbstractHttpEntity; import org.apache.http.entity.ContentType; import org.apache.http.util.Args; class InternalInputStreamEntity extends AbstractHttpEntity { private final InputStream content; private final long length; public InternalInputStreamEntity(final InputStream instream, final long length, final ContentType contentType) { super(); this.content = Args.notNull(instream, "Source input stream"); this.length = length; if (contentType != null) { setContentType(contentType.toString()); } } public boolean isRepeatable() { return false; } public long getContentLength() { return this.length; } public InputStream getContent() throws IOException { return this.content; } public void writeTo(final OutputStream outstream) throws IOException { Args.notNull(outstream, "Output stream"); final InputStream instream = this.content; try { final byte[] buffer = new byte[4096]; int l; if (this.length < 0) { // consume until EOF while ((l = instream.read(buffer)) != -1) { outstream.write(buffer, 0, l); } } else { // consume no more than length long remaining = this.length; while (remaining > 0) { l = instream.read(buffer, 0, (int)Math.min(4096, remaining)); if (l == -1) { break; } outstream.write(buffer, 0, l); remaining -= l; } } } finally { instream.close(); } } public boolean isStreaming() { return true; } } httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/package-info.java0100644 0000000 0000000 00000002444 12301751741 032070 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Simple facade APIs for HttpClient based on the concept of * a fluent interface. */ package org.apache.http.client.fluent; httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/Request.java0100644 0000000 0000000 00000026102 12301751740 031170 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URI; import java.nio.charset.Charset; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.TimeZone; import org.apache.http.Consts; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpHost; import org.apache.http.HttpVersion; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpOptions; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpTrace; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.entity.ContentType; import org.apache.http.protocol.HTTP; public class Request { public static final String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz"; public static final Locale DATE_LOCALE = Locale.US; public static final TimeZone TIME_ZONE = TimeZone.getTimeZone("GMT"); private final InternalHttpRequest request; private final RequestConfig.Builder configBuilder; private SimpleDateFormat dateFormatter; public static Request Get(final URI uri) { return new Request(HttpGet.METHOD_NAME, uri); } public static Request Get(final String uri) { return new Request(HttpGet.METHOD_NAME, URI.create(uri)); } public static Request Head(final URI uri) { return new Request(HttpHead.METHOD_NAME, uri); } public static Request Head(final String uri) { return new Request(HttpHead.METHOD_NAME, URI.create(uri)); } public static Request Post(final URI uri) { return new Request(HttpPost.METHOD_NAME, uri); } public static Request Post(final String uri) { return new Request(HttpPost.METHOD_NAME, URI.create(uri)); } public static Request Put(final URI uri) { return new Request(HttpPut.METHOD_NAME, uri); } public static Request Put(final String uri) { return new Request(HttpPut.METHOD_NAME, URI.create(uri)); } public static Request Trace(final URI uri) { return new Request(HttpTrace.METHOD_NAME, uri); } public static Request Trace(final String uri) { return new Request(HttpTrace.METHOD_NAME, URI.create(uri)); } public static Request Delete(final URI uri) { return new Request(HttpDelete.METHOD_NAME, uri); } public static Request Delete(final String uri) { return new Request(HttpDelete.METHOD_NAME, URI.create(uri)); } public static Request Options(final URI uri) { return new Request(HttpOptions.METHOD_NAME, uri); } public static Request Options(final String uri) { return new Request(HttpOptions.METHOD_NAME, URI.create(uri)); } Request(final String method, final URI requestURI) { super(); this.request = new InternalHttpRequest(method, requestURI); this.configBuilder = RequestConfig.custom(); } InternalHttpRequest prepareRequest() { this.request.setConfig(this.configBuilder.build()); return this.request; } public Response execute() throws ClientProtocolException, IOException { this.request.setConfig(this.configBuilder.build()); return new Response(Executor.CLIENT.execute(this.request)); } public void abort() throws UnsupportedOperationException { this.request.abort(); } //// HTTP header operations public Request addHeader(final Header header) { this.request.addHeader(header); return this; } /** * @since 4.3 */ public Request setHeader(final Header header) { this.request.setHeader(header); return this; } public Request addHeader(final String name, final String value) { this.request.addHeader(name, value); return this; } /** * @since 4.3 */ public Request setHeader(final String name, final String value) { this.request.setHeader(name, value); return this; } public Request removeHeader(final Header header) { this.request.removeHeader(header); return this; } public Request removeHeaders(final String name) { this.request.removeHeaders(name); return this; } public Request setHeaders(final Header... headers) { this.request.setHeaders(headers); return this; } public Request setCacheControl(final String cacheControl) { this.request.setHeader(HttpHeader.CACHE_CONTROL, cacheControl); return this; } private SimpleDateFormat getDateFormat() { if (this.dateFormatter == null) { this.dateFormatter = new SimpleDateFormat(DATE_FORMAT, DATE_LOCALE); this.dateFormatter.setTimeZone(TIME_ZONE); } return this.dateFormatter; } public Request setDate(final Date date) { this.request.setHeader(HttpHeader.DATE, getDateFormat().format(date)); return this; } public Request setIfModifiedSince(final Date date) { this.request.setHeader(HttpHeader.IF_MODIFIED_SINCE, getDateFormat().format(date)); return this; } public Request setIfUnmodifiedSince(final Date date) { this.request.setHeader(HttpHeader.IF_UNMODIFIED_SINCE, getDateFormat().format(date)); return this; } /** * This method has no effect. Do not use. * * @deprecated (4.3) */ @Deprecated public Request config(final String param, final Object object) { return this; } /** * This method has no effect. Do not use. * * @deprecated (4.3) */ @Deprecated public Request removeConfig(final String param) { return this; } //// HTTP protocol parameter operations public Request version(final HttpVersion version) { this.request.setProtocolVersion(version); return this; } /** * This parameter can no longer be used at the request level. *

* This method has no effect. Do not use. * @deprecated (4.3) */ @Deprecated public Request elementCharset(final String charset) { return this; } public Request useExpectContinue() { this.configBuilder.setExpectContinueEnabled(true); return this; } public Request userAgent(final String agent) { this.request.setHeader(HTTP.USER_AGENT, agent); return this; } //// HTTP connection parameter operations public Request socketTimeout(final int timeout) { this.configBuilder.setSocketTimeout(timeout); return this; } public Request connectTimeout(final int timeout) { this.configBuilder.setConnectTimeout(timeout); return this; } public Request staleConnectionCheck(final boolean b) { this.configBuilder.setStaleConnectionCheckEnabled(b); return this; } //// HTTP connection route operations public Request viaProxy(final HttpHost proxy) { this.configBuilder.setProxy(proxy); return this; } //// HTTP entity operations public Request body(final HttpEntity entity) { if (this.request instanceof HttpEntityEnclosingRequest) { ((HttpEntityEnclosingRequest) this.request).setEntity(entity); } else { throw new IllegalStateException(this.request.getMethod() + " request cannot enclose an entity"); } return this; } public Request bodyForm(final Iterable formParams, final Charset charset) { final List paramList = new ArrayList(); for (NameValuePair param : formParams) { paramList.add(param); } final ContentType contentType = ContentType.create(URLEncodedUtils.CONTENT_TYPE, charset); final String s = URLEncodedUtils.format(paramList, charset != null ? charset.name() : null); return bodyString(s, contentType); } public Request bodyForm(final Iterable formParams) { return bodyForm(formParams, Consts.ISO_8859_1); } public Request bodyForm(final NameValuePair... formParams) { return bodyForm(Arrays.asList(formParams), Consts.ISO_8859_1); } public Request bodyString(final String s, final ContentType contentType) { final Charset charset = contentType != null ? contentType.getCharset() : null; byte[] raw; try { raw = charset != null ? s.getBytes(charset.name()) : s.getBytes(); } catch (UnsupportedEncodingException ex) { raw = s.getBytes(); } return body(new InternalByteArrayEntity(raw, contentType)); } public Request bodyFile(final File file, final ContentType contentType) { return body(new InternalFileEntity(file, contentType)); } public Request bodyByteArray(final byte[] b) { return body(new InternalByteArrayEntity(b)); } public Request bodyByteArray(final byte[] b, final int off, final int len) { return body(new InternalByteArrayEntity(b, off, len)); } public Request bodyStream(final InputStream instream) { return body(new InternalInputStreamEntity(instream, -1, null)); } public Request bodyStream(final InputStream instream, final ContentType contentType) { return body(new InternalInputStreamEntity(instream, -1, contentType)); } @Override public String toString() { return this.request.getRequestLine().toString(); } } httpcomponents-client-4.3.3/fluent-hc/src/main/java/org/apache/http/client/fluent/Response.java0100644 0000000 0000000 00000010705 12301751741 031341 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.fluent; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpResponseException; import org.apache.http.client.ResponseHandler; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.ContentType; import org.apache.http.util.EntityUtils; public class Response { private final HttpResponse response; private boolean consumed; Response(final HttpResponse response) { super(); this.response = response; } private void assertNotConsumed() { if (this.consumed) { throw new IllegalStateException("Response content has been already consumed"); } } private void dispose() { if (this.consumed) { return; } try { final HttpEntity entity = this.response.getEntity(); final InputStream content = entity.getContent(); if (content != null) { content.close(); } } catch (final Exception ignore) { } finally { this.consumed = true; } } /** * Discards response content and deallocates all resources associated with it. */ public void discardContent() { dispose(); } /** * Handles the response using the specified {@link ResponseHandler} */ public T handleResponse( final ResponseHandler handler) throws ClientProtocolException, IOException { assertNotConsumed(); try { return handler.handleResponse(this.response); } finally { dispose(); } } public Content returnContent() throws ClientProtocolException, IOException { return handleResponse(new ContentResponseHandler()); } public HttpResponse returnResponse() throws IOException { assertNotConsumed(); try { final HttpEntity entity = this.response.getEntity(); if (entity != null) { final ByteArrayEntity byteArrayEntity = new ByteArrayEntity( EntityUtils.toByteArray(entity)); final ContentType contentType = ContentType.getOrDefault(entity); byteArrayEntity.setContentType(contentType.toString()); this.response.setEntity(byteArrayEntity); } return this.response; } finally { this.consumed = true; } } public void saveContent(final File file) throws IOException { assertNotConsumed(); final StatusLine statusLine = response.getStatusLine(); if (statusLine.getStatusCode() >= 300) { throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase()); } final FileOutputStream out = new FileOutputStream(file); try { final HttpEntity entity = this.response.getEntity(); if (entity != null) { entity.writeTo(out); } } finally { this.consumed = true; out.close(); } } } httpcomponents-client-4.3.3/httpclient/0040755 0000000 0000000 00000000000 12301752536 016776 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/pom.xml0100644 0000000 0000000 00000012131 12301751712 020301 0ustar000000000 0000000 4.0.0 org.apache.httpcomponents httpcomponents-client 4.3.3 httpclient Apache HttpClient HttpComponents Client http://hc.apache.org/httpcomponents-client jar org.apache.httpcomponents httpcore compile commons-logging commons-logging compile commons-codec commons-codec compile junit junit test org.mockito mockito-core test src/main/resources true **/*.properties org.codehaus.mojo build-helper-maven-plugin 1.8 add-source generate-sources add-source src/main/java-deprecated maven-jar-plugin test-jar maven-javadoc-plugin ${hc.javadoc.version} true ${maven.compiler.source} http://download.oracle.com/javase/1.5.0/docs/api/ http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/ javadoc maven-project-info-reports-plugin ${hc.project-info.version} false dependencies dependency-info summary maven-jxr-plugin ${hc.jxr.version} maven-surefire-report-plugin ${hc.surefire-report.version} httpcomponents-client-4.3.3/httpclient/src/0040755 0000000 0000000 00000000000 12301751660 017562 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/0040755 0000000 0000000 00000000000 12301751652 021401 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/0040755 0000000 0000000 00000000000 12301751652 022170 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/0040755 0000000 0000000 00000000000 12301751652 023411 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/0040755 0000000 0000000 00000000000 12301751652 024370 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/0040755 0000000 0000000 00000000000 12301751652 026206 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/0040755 0000000 0000000 00000000000 12301751653 027465 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientAbortMethod.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientAbortMetho0100644 0000000 0000000 00000004525 12301751652 032615 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; /** * This example demonstrates how to abort an HTTP method before its normal completion. */ public class ClientAbortMethod { public final static void main(String[] args) throws Exception { CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpGet httpget = new HttpGet("http://www.apache.org/"); System.out.println("Executing request " + httpget.getURI()); CloseableHttpResponse response = httpclient.execute(httpget); try { System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); // Do not feel like reading the response body // Call abort on the request object httpget.abort(); } finally { response.close(); } } finally { httpclient.close(); } } } ././@LongLink0100644 0000000 0000000 00000000156 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientAuthentication.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientAuthentica0100644 0000000 0000000 00000005531 12301751652 032634 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; /** * A simple example that uses HttpClient to execute an HTTP request against * a target site that requires user authentication. */ public class ClientAuthentication { public static void main(String[] args) throws Exception { CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( new AuthScope("localhost", 443), new UsernamePasswordCredentials("username", "password")); CloseableHttpClient httpclient = HttpClients.custom() .setDefaultCredentialsProvider(credsProvider) .build(); try { HttpGet httpget = new HttpGet("http://localhost/"); System.out.println("Executing request " + httpget.getRequestLine()); CloseableHttpResponse response = httpclient.execute(httpget); try { System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); EntityUtils.consume(response.getEntity()); } finally { response.close(); } } finally { httpclient.close(); } } } ././@LongLink0100644 0000000 0000000 00000000160 12302131604 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientChunkEncodedPost.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientChunkEncod0100644 0000000 0000000 00000006227 12301751652 032573 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import java.io.File; import java.io.FileInputStream; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; /** * Example how to use unbuffered chunk-encoded POST request. */ public class ClientChunkEncodedPost { public static void main(String[] args) throws Exception { if (args.length != 1) { System.out.println("File path not given"); System.exit(1); } CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpPost httppost = new HttpPost("http://localhost/"); File file = new File(args[0]); InputStreamEntity reqEntity = new InputStreamEntity( new FileInputStream(file), -1, ContentType.APPLICATION_OCTET_STREAM); reqEntity.setChunked(true); // It may be more appropriate to use FileEntity class in this particular // instance but we are using a more generic InputStreamEntity to demonstrate // the capability to stream out data from any arbitrary source // // FileEntity entity = new FileEntity(file, "binary/octet-stream"); httppost.setEntity(reqEntity); System.out.println("Executing request: " + httppost.getRequestLine()); CloseableHttpResponse response = httpclient.execute(httppost); try { System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); EntityUtils.consume(response.getEntity()); } finally { response.close(); } } finally { httpclient.close(); } } } ././@LongLink0100644 0000000 0000000 00000000155 12302131604 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientConfiguration.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientConfigurat0100644 0000000 0000000 00000031464 12301751652 032654 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.charset.CodingErrorAction; import java.util.Arrays; import javax.net.ssl.SSLContext; import org.apache.http.Consts; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.ParseException; import org.apache.http.client.CookieStore; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.AuthSchemes; import org.apache.http.client.config.CookieSpecs; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.ConnectionConfig; import org.apache.http.config.MessageConstraints; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.config.SocketConfig; import org.apache.http.conn.DnsResolver; import org.apache.http.conn.HttpConnectionFactory; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.conn.ssl.X509HostnameVerifier; import org.apache.http.impl.DefaultHttpResponseFactory; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.ManagedHttpClientConnectionFactory; import org.apache.http.impl.conn.DefaultHttpResponseParser; import org.apache.http.impl.conn.DefaultHttpResponseParserFactory; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.impl.conn.SystemDefaultDnsResolver; import org.apache.http.impl.io.DefaultHttpRequestWriterFactory; import org.apache.http.io.HttpMessageParser; import org.apache.http.io.HttpMessageParserFactory; import org.apache.http.io.HttpMessageWriterFactory; import org.apache.http.io.SessionInputBuffer; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicLineParser; import org.apache.http.message.LineParser; import org.apache.http.util.CharArrayBuffer; /** * This example demonstrates how to customize and configure the most common aspects * of HTTP request execution and connection management. */ public class ClientConfiguration { public final static void main(String[] args) throws Exception { // Use custom message parser / writer to customize the way HTTP // messages are parsed from and written out to the data stream. HttpMessageParserFactory responseParserFactory = new DefaultHttpResponseParserFactory() { @Override public HttpMessageParser create( SessionInputBuffer buffer, MessageConstraints constraints) { LineParser lineParser = new BasicLineParser() { @Override public Header parseHeader(final CharArrayBuffer buffer) { try { return super.parseHeader(buffer); } catch (ParseException ex) { return new BasicHeader(buffer.toString(), null); } } }; return new DefaultHttpResponseParser( buffer, lineParser, DefaultHttpResponseFactory.INSTANCE, constraints) { @Override protected boolean reject(final CharArrayBuffer line, int count) { // try to ignore all garbage preceding a status line infinitely return false; } }; } }; HttpMessageWriterFactory requestWriterFactory = new DefaultHttpRequestWriterFactory(); // Use a custom connection factory to customize the process of // initialization of outgoing HTTP connections. Beside standard connection // configuration parameters HTTP connection factory can define message // parser / writer routines to be employed by individual connections. HttpConnectionFactory connFactory = new ManagedHttpClientConnectionFactory( requestWriterFactory, responseParserFactory); // Client HTTP connection objects when fully initialized can be bound to // an arbitrary network socket. The process of network socket initialization, // its connection to a remote address and binding to a local one is controlled // by a connection socket factory. // SSL context for secure connections can be created either based on // system or application specific properties. SSLContext sslcontext = SSLContexts.createSystemDefault(); // Use custom hostname verifier to customize SSL hostname verification. X509HostnameVerifier hostnameVerifier = new BrowserCompatHostnameVerifier(); // Create a registry of custom connection socket factories for supported // protocol schemes. Registry socketFactoryRegistry = RegistryBuilder.create() .register("http", PlainConnectionSocketFactory.INSTANCE) .register("https", new SSLConnectionSocketFactory(sslcontext, hostnameVerifier)) .build(); // Use custom DNS resolver to override the system DNS resolution. DnsResolver dnsResolver = new SystemDefaultDnsResolver() { @Override public InetAddress[] resolve(final String host) throws UnknownHostException { if (host.equalsIgnoreCase("myhost")) { return new InetAddress[] { InetAddress.getByAddress(new byte[] {127, 0, 0, 1}) }; } else { return super.resolve(host); } } }; // Create a connection manager with custom configuration. PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager( socketFactoryRegistry, connFactory, dnsResolver); // Create socket configuration SocketConfig socketConfig = SocketConfig.custom() .setTcpNoDelay(true) .build(); // Configure the connection manager to use socket configuration either // by default or for a specific host. connManager.setDefaultSocketConfig(socketConfig); connManager.setSocketConfig(new HttpHost("somehost", 80), socketConfig); // Create message constraints MessageConstraints messageConstraints = MessageConstraints.custom() .setMaxHeaderCount(200) .setMaxLineLength(2000) .build(); // Create connection configuration ConnectionConfig connectionConfig = ConnectionConfig.custom() .setMalformedInputAction(CodingErrorAction.IGNORE) .setUnmappableInputAction(CodingErrorAction.IGNORE) .setCharset(Consts.UTF_8) .setMessageConstraints(messageConstraints) .build(); // Configure the connection manager to use connection configuration either // by default or for a specific host. connManager.setDefaultConnectionConfig(connectionConfig); connManager.setConnectionConfig(new HttpHost("somehost", 80), ConnectionConfig.DEFAULT); // Configure total max or per route limits for persistent connections // that can be kept in the pool or leased by the connection manager. connManager.setMaxTotal(100); connManager.setDefaultMaxPerRoute(10); connManager.setMaxPerRoute(new HttpRoute(new HttpHost("somehost", 80)), 20); // Use custom cookie store if necessary. CookieStore cookieStore = new BasicCookieStore(); // Use custom credentials provider if necessary. CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); // Create global request configuration RequestConfig defaultRequestConfig = RequestConfig.custom() .setCookieSpec(CookieSpecs.BEST_MATCH) .setExpectContinueEnabled(true) .setStaleConnectionCheckEnabled(true) .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST)) .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)) .build(); // Create an HttpClient with the given custom dependencies and configuration. CloseableHttpClient httpclient = HttpClients.custom() .setConnectionManager(connManager) .setDefaultCookieStore(cookieStore) .setDefaultCredentialsProvider(credentialsProvider) .setProxy(new HttpHost("myproxy", 8080)) .setDefaultRequestConfig(defaultRequestConfig) .build(); try { HttpGet httpget = new HttpGet("http://www.apache.org/"); // Request configuration can be overridden at the request level. // They will take precedence over the one set at the client level. RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig) .setSocketTimeout(5000) .setConnectTimeout(5000) .setConnectionRequestTimeout(5000) .setProxy(new HttpHost("myotherproxy", 8080)) .build(); httpget.setConfig(requestConfig); // Execution context can be customized locally. HttpClientContext context = HttpClientContext.create(); // Contextual attributes set the local context level will take // precedence over those set at the client level. context.setCookieStore(cookieStore); context.setCredentialsProvider(credentialsProvider); System.out.println("executing request " + httpget.getURI()); CloseableHttpResponse response = httpclient.execute(httpget, context); try { HttpEntity entity = response.getEntity(); System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); if (entity != null) { System.out.println("Response content length: " + entity.getContentLength()); } System.out.println("----------------------------------------"); // Once the request has been executed the local context can // be used to examine updated state and various objects affected // by the request execution. // Last executed request context.getRequest(); // Execution route context.getHttpRoute(); // Target auth state context.getTargetAuthState(); // Proxy auth state context.getTargetAuthState(); // Cookie origin context.getCookieOrigin(); // Cookie spec used context.getCookieSpec(); // User security token context.getUserToken(); } finally { response.close(); } } finally { httpclient.close(); } } } ././@LongLink0100644 0000000 0000000 00000000161 12302131604 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientConnectionRelease.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientConnection0100644 0000000 0000000 00000006371 12301751652 032651 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import java.io.IOException; import java.io.InputStream; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; /** * This example demonstrates the recommended way of using API to make sure * the underlying connection gets released back to the connection manager. */ public class ClientConnectionRelease { public final static void main(String[] args) throws Exception { CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpGet httpget = new HttpGet("http://localhost/"); System.out.println("Executing request " + httpget.getRequestLine()); CloseableHttpResponse response = httpclient.execute(httpget); try { System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); // Get hold of the response entity HttpEntity entity = response.getEntity(); // If the response does not enclose an entity, there is no need // to bother about connection release if (entity != null) { InputStream instream = entity.getContent(); try { instream.read(); // do something useful with the response } catch (IOException ex) { // In case of an IOException the connection will be released // back to the connection manager automatically throw ex; } finally { // Closing the input stream will trigger connection release instream.close(); } } } finally { response.close(); } } finally { httpclient.close(); } } } ././@LongLink0100644 0000000 0000000 00000000155 12302131604 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientCustomContext.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientCustomCont0100644 0000000 0000000 00000006202 12301751652 032641 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import java.util.List; import org.apache.http.client.CookieStore; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; /** * This example demonstrates the use of a local HTTP context populated with * custom attributes. */ public class ClientCustomContext { public final static void main(String[] args) throws Exception { CloseableHttpClient httpclient = HttpClients.createDefault(); try { // Create a local instance of cookie store CookieStore cookieStore = new BasicCookieStore(); // Create local HTTP context HttpClientContext localContext = HttpClientContext.create(); // Bind custom cookie store to the local context localContext.setCookieStore(cookieStore); HttpGet httpget = new HttpGet("http://localhost/"); System.out.println("Executing request " + httpget.getRequestLine()); // Pass local context as a parameter CloseableHttpResponse response = httpclient.execute(httpget, localContext); try { System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); List cookies = cookieStore.getCookies(); for (int i = 0; i < cookies.size(); i++) { System.out.println("Local cookie: " + cookies.get(i)); } EntityUtils.consume(response.getEntity()); } finally { response.close(); } } finally { httpclient.close(); } } } ././@LongLink0100644 0000000 0000000 00000000151 12302131604 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientCustomSSL.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientCustomSSL.0100644 0000000 0000000 00000007210 12301751652 032455 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import java.io.File; import java.io.FileInputStream; import java.security.KeyStore; import javax.net.ssl.SSLContext; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; /** * This example demonstrates how to create secure connections with a custom SSL * context. */ public class ClientCustomSSL { public final static void main(String[] args) throws Exception { KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); FileInputStream instream = new FileInputStream(new File("my.keystore")); try { trustStore.load(instream, "nopassword".toCharArray()); } finally { instream.close(); } // Trust own CA and all self-signed certs SSLContext sslcontext = SSLContexts.custom() .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()) .build(); // Allow TLSv1 protocol only SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); CloseableHttpClient httpclient = HttpClients.custom() .setSSLSocketFactory(sslsf) .build(); try { HttpGet httpget = new HttpGet("https://localhost/"); System.out.println("executing request" + httpget.getRequestLine()); CloseableHttpResponse response = httpclient.execute(httpget); try { HttpEntity entity = response.getEntity(); System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); if (entity != null) { System.out.println("Response content length: " + entity.getContentLength()); } EntityUtils.consume(entity); } finally { response.close(); } } finally { httpclient.close(); } } } ././@LongLink0100644 0000000 0000000 00000000167 12302131604 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientEvictExpiredConnections.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientEvictExpir0100644 0000000 0000000 00000010706 12301751652 032631 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import java.util.concurrent.TimeUnit; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.util.EntityUtils; /** * Example demonstrating how to evict expired and idle connections * from the connection pool. */ public class ClientEvictExpiredConnections { public static void main(String[] args) throws Exception { PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); cm.setMaxTotal(100); CloseableHttpClient httpclient = HttpClients.custom() .setConnectionManager(cm) .build(); try { // create an array of URIs to perform GETs on String[] urisToGet = { "http://hc.apache.org/", "http://hc.apache.org/httpcomponents-core-ga/", "http://hc.apache.org/httpcomponents-client-ga/", }; IdleConnectionEvictor connEvictor = new IdleConnectionEvictor(cm); connEvictor.start(); for (int i = 0; i < urisToGet.length; i++) { String requestURI = urisToGet[i]; HttpGet request = new HttpGet(requestURI); System.out.println("Executing request " + requestURI); CloseableHttpResponse response = httpclient.execute(request); try { System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); EntityUtils.consume(response.getEntity()); } finally { response.close(); } } // Sleep 10 sec and let the connection evictor do its job Thread.sleep(20000); // Shut down the evictor thread connEvictor.shutdown(); connEvictor.join(); } finally { httpclient.close(); } } public static class IdleConnectionEvictor extends Thread { private final HttpClientConnectionManager connMgr; private volatile boolean shutdown; public IdleConnectionEvictor(HttpClientConnectionManager connMgr) { super(); this.connMgr = connMgr; } @Override public void run() { try { while (!shutdown) { synchronized (this) { wait(5000); // Close expired connections connMgr.closeExpiredConnections(); // Optionally, close connections // that have been idle longer than 5 sec connMgr.closeIdleConnections(5, TimeUnit.SECONDS); } } } catch (InterruptedException ex) { // terminate } } public void shutdown() { shutdown = true; synchronized (this) { notifyAll(); } } } } ././@LongLink0100644 0000000 0000000 00000000154 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientExecuteProxy.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientExecutePro0100644 0000000 0000000 00000005244 12301751652 032633 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; /** * How to send a request via proxy. * * @since 4.0 */ public class ClientExecuteProxy { public static void main(String[] args)throws Exception { CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpHost target = new HttpHost("localhost", 443, "https"); HttpHost proxy = new HttpHost("127.0.0.1", 8080, "http"); RequestConfig config = RequestConfig.custom() .setProxy(proxy) .build(); HttpGet request = new HttpGet("/"); request.setConfig(config); System.out.println("Executing request " + request.getRequestLine() + " to " + target + " via " + proxy); CloseableHttpResponse response = httpclient.execute(target, request); try { System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); EntityUtils.consume(response.getEntity()); } finally { response.close(); } } finally { httpclient.close(); } } } ././@LongLink0100644 0000000 0000000 00000000154 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientExecuteSOCKS.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientExecuteSOC0100644 0000000 0000000 00000011273 12301751652 032516 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.Socket; import java.net.SocketTimeoutException; import org.apache.http.HttpHost; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; /** * How to send a request via SOCKS proxy. * * @since 4.1 */ public class ClientExecuteSOCKS { public static void main(String[] args)throws Exception { Registry reg = RegistryBuilder.create() .register("http", new MyConnectionSocketFactory()) .build(); PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(reg); CloseableHttpClient httpclient = HttpClients.custom() .setConnectionManager(cm) .build(); try { InetSocketAddress socksaddr = new InetSocketAddress("mysockshost", 1234); HttpClientContext context = HttpClientContext.create(); context.setAttribute("socks.address", socksaddr); HttpHost target = new HttpHost("localhost", 80, "http"); HttpGet request = new HttpGet("/"); System.out.println("Executing request " + request + " to " + target + " via SOCKS proxy " + socksaddr); CloseableHttpResponse response = httpclient.execute(target, request); try { System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); EntityUtils.consume(response.getEntity()); } finally { response.close(); } } finally { httpclient.close(); } } static class MyConnectionSocketFactory implements ConnectionSocketFactory { public Socket createSocket(final HttpContext context) throws IOException { InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socks.address"); Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr); return new Socket(proxy); } public Socket connectSocket( final int connectTimeout, final Socket socket, final HttpHost host, final InetSocketAddress remoteAddress, final InetSocketAddress localAddress, final HttpContext context) throws IOException, ConnectTimeoutException { Socket sock; if (socket != null) { sock = socket; } else { sock = createSocket(context); } if (localAddress != null) { sock.bind(localAddress); } try { sock.connect(remoteAddress, connectTimeout); } catch (SocketTimeoutException ex) { throw new ConnectTimeoutException(ex, host, remoteAddress.getAddress()); } return sock; } } } ././@LongLink0100644 0000000 0000000 00000000151 12302131604 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientFormLogin.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientFormLogin.0100644 0000000 0000000 00000010035 12301751652 032514 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import java.net.URI; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; /** * A example that demonstrates how HttpClient APIs can be used to perform * form-based logon. */ public class ClientFormLogin { public static void main(String[] args) throws Exception { BasicCookieStore cookieStore = new BasicCookieStore(); CloseableHttpClient httpclient = HttpClients.custom() .setDefaultCookieStore(cookieStore) .build(); try { HttpGet httpget = new HttpGet("https://someportal/"); CloseableHttpResponse response1 = httpclient.execute(httpget); try { HttpEntity entity = response1.getEntity(); System.out.println("Login form get: " + response1.getStatusLine()); EntityUtils.consume(entity); System.out.println("Initial set of cookies:"); List cookies = cookieStore.getCookies(); if (cookies.isEmpty()) { System.out.println("None"); } else { for (int i = 0; i < cookies.size(); i++) { System.out.println("- " + cookies.get(i).toString()); } } } finally { response1.close(); } HttpUriRequest login = RequestBuilder.post() .setUri(new URI("https://someportal/")) .addParameter("IDToken1", "username") .addParameter("IDToken2", "password") .build(); CloseableHttpResponse response2 = httpclient.execute(login); try { HttpEntity entity = response2.getEntity(); System.out.println("Login form get: " + response2.getStatusLine()); EntityUtils.consume(entity); System.out.println("Post logon cookies:"); List cookies = cookieStore.getCookies(); if (cookies.isEmpty()) { System.out.println("None"); } else { for (int i = 0; i < cookies.size(); i++) { System.out.println("- " + cookies.get(i).toString()); } } } finally { response2.close(); } } finally { httpclient.close(); } } } ././@LongLink0100644 0000000 0000000 00000000166 12302131604 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientMultiThreadedExecution.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientMultiThrea0100644 0000000 0000000 00000011210 12301751652 032614 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; /** * An example that performs GETs from multiple threads. * */ public class ClientMultiThreadedExecution { public static void main(String[] args) throws Exception { // Create an HttpClient with the ThreadSafeClientConnManager. // This connection manager must be used if more than one thread will // be using the HttpClient. PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); cm.setMaxTotal(100); CloseableHttpClient httpclient = HttpClients.custom() .setConnectionManager(cm) .build(); try { // create an array of URIs to perform GETs on String[] urisToGet = { "http://hc.apache.org/", "http://hc.apache.org/httpcomponents-core-ga/", "http://hc.apache.org/httpcomponents-client-ga/", }; // create a thread for each URI GetThread[] threads = new GetThread[urisToGet.length]; for (int i = 0; i < threads.length; i++) { HttpGet httpget = new HttpGet(urisToGet[i]); threads[i] = new GetThread(httpclient, httpget, i + 1); } // start the threads for (int j = 0; j < threads.length; j++) { threads[j].start(); } // join the threads for (int j = 0; j < threads.length; j++) { threads[j].join(); } } finally { httpclient.close(); } } /** * A thread that performs a GET. */ static class GetThread extends Thread { private final CloseableHttpClient httpClient; private final HttpContext context; private final HttpGet httpget; private final int id; public GetThread(CloseableHttpClient httpClient, HttpGet httpget, int id) { this.httpClient = httpClient; this.context = new BasicHttpContext(); this.httpget = httpget; this.id = id; } /** * Executes the GetMethod and prints some status information. */ @Override public void run() { try { System.out.println(id + " - about to get something from " + httpget.getURI()); CloseableHttpResponse response = httpClient.execute(httpget, context); try { System.out.println(id + " - get executed"); // get the response body as an array of bytes HttpEntity entity = response.getEntity(); if (entity != null) { byte[] bytes = EntityUtils.toByteArray(entity); System.out.println(id + " - " + bytes.length + " bytes read"); } } finally { response.close(); } } catch (Exception e) { System.out.println(id + " - error: " + e); } } } } ././@LongLink0100644 0000000 0000000 00000000175 12302131604 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientPreemptive0100644 0000000 0000000 00000007543 12301751653 032675 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthCache; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; /** * An example of HttpClient can be customized to authenticate * preemptively using BASIC scheme. * * Generally, preemptive authentication can be considered less * secure than a response to an authentication challenge * and therefore discouraged. */ public class ClientPreemptiveBasicAuthentication { public static void main(String[] args) throws Exception { HttpHost target = new HttpHost("localhost", 80, "http"); CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( new AuthScope(target.getHostName(), target.getPort()), new UsernamePasswordCredentials("username", "password")); CloseableHttpClient httpclient = HttpClients.custom() .setDefaultCredentialsProvider(credsProvider).build(); try { // Create AuthCache instance AuthCache authCache = new BasicAuthCache(); // Generate BASIC scheme object and add it to the local // auth cache BasicScheme basicAuth = new BasicScheme(); authCache.put(target, basicAuth); // Add AuthCache to the execution context HttpClientContext localContext = HttpClientContext.create(); localContext.setAuthCache(authCache); HttpGet httpget = new HttpGet("/"); System.out.println("Executing request " + httpget.getRequestLine() + " to target " + target); for (int i = 0; i < 3; i++) { CloseableHttpResponse response = httpclient.execute(target, httpget, localContext); try { System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); EntityUtils.consume(response.getEntity()); } finally { response.close(); } } } finally { httpclient.close(); } } } ././@LongLink0100644 0000000 0000000 00000000176 12302131604 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientPreemptiveDigestAuthentication.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientPreemptive0100644 0000000 0000000 00000010177 12301751653 032672 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthCache; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.impl.auth.DigestScheme; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; /** * An example of HttpClient can be customized to authenticate * preemptively using DIGEST scheme. *

* Generally, preemptive authentication can be considered less * secure than a response to an authentication challenge * and therefore discouraged. */ public class ClientPreemptiveDigestAuthentication { public static void main(String[] args) throws Exception { HttpHost target = new HttpHost("localhost", 80, "http"); CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( new AuthScope(target.getHostName(), target.getPort()), new UsernamePasswordCredentials("username", "password")); CloseableHttpClient httpclient = HttpClients.custom() .setDefaultCredentialsProvider(credsProvider) .build(); try { // Create AuthCache instance AuthCache authCache = new BasicAuthCache(); // Generate DIGEST scheme object, initialize it and add it to the local // auth cache DigestScheme digestAuth = new DigestScheme(); // Suppose we already know the realm name digestAuth.overrideParamter("realm", "some realm"); // Suppose we already know the expected nonce value digestAuth.overrideParamter("nonce", "whatever"); authCache.put(target, digestAuth); // Add AuthCache to the execution context HttpClientContext localContext = HttpClientContext.create(); localContext.setAuthCache(authCache); HttpGet httpget = new HttpGet("/"); System.out.println("Executing request " + httpget.getRequestLine() + " to target " + target); for (int i = 0; i < 3; i++) { CloseableHttpResponse response = httpclient.execute(target, httpget, localContext); try { System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); EntityUtils.consume(response.getEntity()); } finally { response.close(); } } } finally { httpclient.close(); } } } ././@LongLink0100644 0000000 0000000 00000000163 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientProxyAuthentication.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientProxyAuthe0100644 0000000 0000000 00000006363 12301751653 032664 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; /** * A simple example that uses HttpClient to execute an HTTP request * over a secure connection tunneled through an authenticating proxy. */ public class ClientProxyAuthentication { public static void main(String[] args) throws Exception { CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( new AuthScope("localhost", 8080), new UsernamePasswordCredentials("username", "password")); CloseableHttpClient httpclient = HttpClients.custom() .setDefaultCredentialsProvider(credsProvider).build(); try { HttpHost target = new HttpHost("www.verisign.com", 443, "https"); HttpHost proxy = new HttpHost("localhost", 8080); RequestConfig config = RequestConfig.custom() .setProxy(proxy) .build(); HttpGet httpget = new HttpGet("/"); httpget.setConfig(config); System.out.println("Executing request " + httpget.getRequestLine() + " to " + target + " via " + proxy); CloseableHttpResponse response = httpclient.execute(target, httpget); try { System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); EntityUtils.consume(response.getEntity()); } finally { response.close(); } } finally { httpclient.close(); } } } ././@LongLink0100644 0000000 0000000 00000000161 12302131604 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientWithRequestFuture.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientWithReques0100644 0000000 0000000 00000012450 12301751653 032646 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import java.io.IOException; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.concurrent.FutureCallback; import org.apache.http.impl.client.FutureRequestExecutionService; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpRequestFutureTask; public class ClientWithRequestFuture { public static void main(String[] args) throws Exception { // the simplest way to create a HttpAsyncClientWithFuture HttpClient httpclient = HttpClientBuilder.create() .setMaxConnPerRoute(5) .setMaxConnTotal(5).build(); ExecutorService execService = Executors.newFixedThreadPool(5); FutureRequestExecutionService requestExecService = new FutureRequestExecutionService( httpclient, execService); try { // Because things are asynchronous, you must provide a ResponseHandler ResponseHandler handler = new ResponseHandler() { public Boolean handleResponse(HttpResponse response) throws ClientProtocolException, IOException { // simply return true if the status was OK return response.getStatusLine().getStatusCode() == 200; } }; // Simple request ... HttpGet request1 = new HttpGet("http://google.com"); HttpRequestFutureTask futureTask1 = requestExecService.execute(request1, HttpClientContext.create(), handler); Boolean wasItOk1 = futureTask1.get(); System.out.println("It was ok? " + wasItOk1); // Cancel a request try { HttpGet request2 = new HttpGet("http://google.com"); HttpRequestFutureTask futureTask2 = requestExecService.execute(request2, HttpClientContext.create(), handler); futureTask2.cancel(true); Boolean wasItOk2 = futureTask2.get(); System.out.println("It was cancelled so it should never print this: " + wasItOk2); } catch (CancellationException e) { System.out.println("We cancelled it, so this is expected"); } // Request with a timeout HttpGet request3 = new HttpGet("http://google.com"); HttpRequestFutureTask futureTask3 = requestExecService.execute(request3, HttpClientContext.create(), handler); Boolean wasItOk3 = futureTask3.get(10, TimeUnit.SECONDS); System.out.println("It was ok? " + wasItOk3); FutureCallback callback = new FutureCallback() { public void completed(Boolean result) { System.out.println("completed with " + result); } public void failed(Exception ex) { System.out.println("failed with " + ex.getMessage()); } public void cancelled() { System.out.println("cancelled"); } }; // Simple request with a callback HttpGet request4 = new HttpGet("http://google.com"); // using a null HttpContext here since it is optional // the callback will be called when the task completes, fails, or is cancelled HttpRequestFutureTask futureTask4 = requestExecService.execute(request4, HttpClientContext.create(), handler, callback); Boolean wasItOk4 = futureTask4.get(10, TimeUnit.SECONDS); System.out.println("It was ok? " + wasItOk4); } finally { requestExecService.close(); } } }././@LongLink0100644 0000000 0000000 00000000163 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientWithResponseHandler.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ClientWithRespon0100644 0000000 0000000 00000006125 12301751652 032651 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import java.io.IOException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; /** * This example demonstrates the use of the {@link ResponseHandler} to simplify * the process of processing the HTTP response and releasing associated resources. */ public class ClientWithResponseHandler { public final static void main(String[] args) throws Exception { CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpGet httpget = new HttpGet("http://localhost/"); System.out.println("Executing request " + httpget.getRequestLine()); // Create a custom response handler ResponseHandler responseHandler = new ResponseHandler() { public String handleResponse( final HttpResponse response) throws ClientProtocolException, IOException { int status = response.getStatusLine().getStatusCode(); if (status >= 200 && status < 300) { HttpEntity entity = response.getEntity(); return entity != null ? EntityUtils.toString(entity) : null; } else { throw new ClientProtocolException("Unexpected response status: " + status); } } }; String responseBody = httpclient.execute(httpget, responseHandler); System.out.println("----------------------------------------"); System.out.println(responseBody); } finally { httpclient.close(); } } } ././@LongLink0100644 0000000 0000000 00000000151 12302131604 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ProxyTunnelDemo.javahttpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/ProxyTunnelDemo.0100644 0000000 0000000 00000005423 12301751652 032602 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Writer; import java.net.Socket; import org.apache.http.HttpHost; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.impl.client.ProxyClient; import org.apache.http.protocol.HTTP; /** * Example code for using {@link ProxyClient} in order to establish a tunnel through an HTTP proxy. */ public class ProxyTunnelDemo { public final static void main(String[] args) throws Exception { ProxyClient proxyClient = new ProxyClient(); HttpHost target = new HttpHost("www.yahoo.com", 80); HttpHost proxy = new HttpHost("localhost", 8888); UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("user", "pwd"); Socket socket = proxyClient.tunnel(proxy, target, credentials); try { Writer out = new OutputStreamWriter(socket.getOutputStream(), HTTP.DEF_CONTENT_CHARSET); out.write("GET / HTTP/1.1\r\n"); out.write("Host: " + target.toHostString() + "\r\n"); out.write("Agent: whatever\r\n"); out.write("Connection: close\r\n"); out.write("\r\n"); out.flush(); BufferedReader in = new BufferedReader( new InputStreamReader(socket.getInputStream(), HTTP.DEF_CONTENT_CHARSET)); String line = null; while ((line = in.readLine()) != null) { System.out.println(line); } } finally { socket.close(); } } } httpcomponents-client-4.3.3/httpclient/src/examples/org/apache/http/examples/client/QuickStart.java0100644 0000000 0000000 00000007223 12301751652 032422 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.client; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; public class QuickStart { public static void main(String[] args) throws Exception { CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpGet httpGet = new HttpGet("http://targethost/homepage"); CloseableHttpResponse response1 = httpclient.execute(httpGet); // The underlying HTTP connection is still held by the response object // to allow the response content to be streamed directly from the network socket. // In order to ensure correct deallocation of system resources // the user MUST either fully consume the response content or abort request // execution by calling CloseableHttpResponse#close(). try { System.out.println(response1.getStatusLine()); HttpEntity entity1 = response1.getEntity(); // do something useful with the response body // and ensure it is fully consumed EntityUtils.consume(entity1); } finally { response1.close(); } HttpPost httpPost = new HttpPost("http://targethost/login"); List nvps = new ArrayList (); nvps.add(new BasicNameValuePair("username", "vip")); nvps.add(new BasicNameValuePair("password", "secret")); httpPost.setEntity(new UrlEncodedFormEntity(nvps)); CloseableHttpResponse response2 = httpclient.execute(httpPost); try { System.out.println(response2.getStatusLine()); HttpEntity entity2 = response2.getEntity(); // do something useful with the response body // and ensure it is fully consumed EntityUtils.consume(entity2); } finally { response2.close(); } } finally { httpclient.close(); } } } httpcomponents-client-4.3.3/httpclient/src/main/0040755 0000000 0000000 00000000000 12301751666 020514 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/0040755 0000000 0000000 00000000000 12301751666 021435 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/0040755 0000000 0000000 00000000000 12301751666 022224 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/0040755 0000000 0000000 00000000000 12301751666 023445 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/0040755 0000000 0000000 00000000000 12301751711 024413 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/0040755 0000000 0000000 00000000000 12301751701 025353 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/AUTH.java0100644 0000000 0000000 00000003630 12301751700 026755 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import org.apache.http.annotation.Immutable; /** * Constants and static helpers related to the HTTP authentication. * * * @since 4.0 */ @Immutable public final class AUTH { /** * The www authenticate challange header. */ public static final String WWW_AUTH = "WWW-Authenticate"; /** * The www authenticate response header. */ public static final String WWW_AUTH_RESP = "Authorization"; /** * The proxy authenticate challange header. */ public static final String PROXY_AUTH = "Proxy-Authenticate"; /** * The proxy authenticate response header. */ public static final String PROXY_AUTH_RESP = "Proxy-Authorization"; private AUTH() { } } ././@LongLink0100644 0000000 0000000 00000000147 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/AuthenticationException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/AuthenticationException.ja0100644 0000000 0000000 00000004505 12301751700 032525 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import org.apache.http.ProtocolException; import org.apache.http.annotation.Immutable; /** * Signals a failure in authentication process * * * @since 4.0 */ @Immutable public class AuthenticationException extends ProtocolException { private static final long serialVersionUID = -6794031905674764776L; /** * Creates a new AuthenticationException with a null detail message. */ public AuthenticationException() { super(); } /** * Creates a new AuthenticationException with the specified message. * * @param message the exception detail message */ public AuthenticationException(final String message) { super(message); } /** * Creates a new AuthenticationException with the specified detail message and cause. * * @param message the exception detail message * @param cause the Throwable that caused this exception, or null * if the cause is unavailable, unknown, or not a Throwable */ public AuthenticationException(final String message, final Throwable cause) { super(message, cause); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/AuthOption.java0100644 0000000 0000000 00000003647 12301751700 030316 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import org.apache.http.annotation.Immutable; import org.apache.http.util.Args; /** * @since 4.2 */ @Immutable public final class AuthOption { private final AuthScheme authScheme; private final Credentials creds; public AuthOption(final AuthScheme authScheme, final Credentials creds) { super(); Args.notNull(authScheme, "Auth scheme"); Args.notNull(creds, "User credentials"); this.authScheme = authScheme; this.creds = creds; } public AuthScheme getAuthScheme() { return this.authScheme; } public Credentials getCredentials() { return this.creds; } @Override public String toString() { return this.authScheme.toString(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/AuthProtocolState.java0100644 0000000 0000000 00000002435 12301751700 031642 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; public enum AuthProtocolState { UNCHALLENGED, CHALLENGED, HANDSHAKE, FAILURE, SUCCESS } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/AuthScheme.java0100644 0000000 0000000 00000011341 12301751700 030240 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import org.apache.http.Header; import org.apache.http.HttpRequest; /** * This interface represents an abstract challenge-response oriented * authentication scheme. *

* An authentication scheme should be able to support the following * functions: *

    *
  • Parse and process the challenge sent by the target server * in response to request for a protected resource *
  • Provide its textual designation *
  • Provide its parameters, if available *
  • Provide the realm this authentication scheme is applicable to, * if available *
  • Generate authorization string for the given set of credentials * and the HTTP request in response to the authorization challenge. *
*

* Authentication schemes may be stateful involving a series of * challenge-response exchanges. *

* IMPORTANT: implementations of this interface MUST also implement {@link ContextAwareAuthScheme} * interface in order to remain API compatible with newer versions of HttpClient. * * @since 4.0 */ public interface AuthScheme { /** * Processes the given challenge token. Some authentication schemes * may involve multiple challenge-response exchanges. Such schemes must be able * to maintain the state information when dealing with sequential challenges * * @param header the challenge header */ void processChallenge(final Header header) throws MalformedChallengeException; /** * Returns textual designation of the given authentication scheme. * * @return the name of the given authentication scheme */ String getSchemeName(); /** * Returns authentication parameter with the given name, if available. * * @param name The name of the parameter to be returned * * @return the parameter with the given name */ String getParameter(final String name); /** * Returns authentication realm. If the concept of an authentication * realm is not applicable to the given authentication scheme, returns * null. * * @return the authentication realm */ String getRealm(); /** * Tests if the authentication scheme is provides authorization on a per * connection basis instead of usual per request basis * * @return true if the scheme is connection based, false * if the scheme is request based. */ boolean isConnectionBased(); /** * Authentication process may involve a series of challenge-response exchanges. * This method tests if the authorization process has been completed, either * successfully or unsuccessfully, that is, all the required authorization * challenges have been processed in their entirety. * * @return true if the authentication process has been completed, * false otherwise. */ boolean isComplete(); /** * Produces an authorization string for the given set of {@link Credentials}. * * @param credentials The set of credentials to be used for athentication * @param request The request being authenticated * @throws AuthenticationException if authorization string cannot * be generated due to an authentication failure * * @return the authorization string * * @deprecated (4.1) Use {@link ContextAwareAuthScheme#authenticate(Credentials, HttpRequest, org.apache.http.protocol.HttpContext)} */ @Deprecated Header authenticate(Credentials credentials, HttpRequest request) throws AuthenticationException; } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/AuthSchemeFactory.java0100644 0000000 0000000 00000003200 12301751701 031564 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import org.apache.http.params.HttpParams; /** * Factory for {@link AuthScheme} implementations. * * @since 4.0 * * @deprecated (4.3) use {@link AuthSchemeProvider} */ @Deprecated public interface AuthSchemeFactory { /** * Creates an instance of {@link AuthScheme} using given HTTP parameters. * * @param params HTTP parameters. * * @return auth scheme. */ AuthScheme newInstance(HttpParams params); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/AuthSchemeProvider.java0100644 0000000 0000000 00000002765 12301751700 031765 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import org.apache.http.protocol.HttpContext; /** * Factory for {@link AuthScheme} implementations. * * @since 4.3 */ public interface AuthSchemeProvider { /** * Creates an instance of {@link AuthScheme}. * * @return auth scheme. */ AuthScheme create(HttpContext context); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/AuthSchemeRegistry.java0100644 0000000 0000000 00000012660 12301751701 031777 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.http.HttpRequest; import org.apache.http.annotation.ThreadSafe; import org.apache.http.config.Lookup; import org.apache.http.params.HttpParams; import org.apache.http.protocol.ExecutionContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Authentication scheme registry that can be used to obtain the corresponding * authentication scheme implementation for a given type of authorization challenge. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.config.Registry} */ @ThreadSafe @Deprecated public final class AuthSchemeRegistry implements Lookup { private final ConcurrentHashMap registeredSchemes; public AuthSchemeRegistry() { super(); this.registeredSchemes = new ConcurrentHashMap(); } /** * Registers a {@link AuthSchemeFactory} with the given identifier. If a factory with the * given name already exists it will be overridden. This name is the same one used to * retrieve the {@link AuthScheme authentication scheme} from {@link #getAuthScheme}. * *

* Please note that custom authentication preferences, if used, need to be updated accordingly * for the new {@link AuthScheme authentication scheme} to take effect. *

* * @param name the identifier for this scheme * @param factory the {@link AuthSchemeFactory} class to register * * @see #getAuthScheme */ public void register( final String name, final AuthSchemeFactory factory) { Args.notNull(name, "Name"); Args.notNull(factory, "Authentication scheme factory"); registeredSchemes.put(name.toLowerCase(Locale.ENGLISH), factory); } /** * Unregisters the class implementing an {@link AuthScheme authentication scheme} with * the given name. * * @param name the identifier of the class to unregister */ public void unregister(final String name) { Args.notNull(name, "Name"); registeredSchemes.remove(name.toLowerCase(Locale.ENGLISH)); } /** * Gets the {@link AuthScheme authentication scheme} with the given name. * * @param name the {@link AuthScheme authentication scheme} identifier * @param params the {@link HttpParams HTTP parameters} for the authentication * scheme. * * @return {@link AuthScheme authentication scheme} * * @throws IllegalStateException if a scheme with the given name cannot be found */ public AuthScheme getAuthScheme(final String name, final HttpParams params) throws IllegalStateException { Args.notNull(name, "Name"); final AuthSchemeFactory factory = registeredSchemes.get(name.toLowerCase(Locale.ENGLISH)); if (factory != null) { return factory.newInstance(params); } else { throw new IllegalStateException("Unsupported authentication scheme: " + name); } } /** * Obtains a list containing the names of all registered {@link AuthScheme authentication * schemes} * * @return list of registered scheme names */ public List getSchemeNames() { return new ArrayList(registeredSchemes.keySet()); } /** * Populates the internal collection of registered {@link AuthScheme authentication schemes} * with the content of the map passed as a parameter. * * @param map authentication schemes */ public void setItems(final Map map) { if (map == null) { return; } registeredSchemes.clear(); registeredSchemes.putAll(map); } public AuthSchemeProvider lookup(final String name) { return new AuthSchemeProvider() { public AuthScheme create(final HttpContext context) { final HttpRequest request = (HttpRequest) context.getAttribute( ExecutionContext.HTTP_REQUEST); return getAuthScheme(name, request.getParams()); } }; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/AuthScope.java0100644 0000000 0000000 00000022246 12301751700 030113 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import java.util.Locale; import org.apache.http.HttpHost; import org.apache.http.annotation.Immutable; import org.apache.http.util.Args; import org.apache.http.util.LangUtils; /** * The class represents an authentication scope consisting of a host name, * a port number, a realm name and an authentication scheme name which * {@link Credentials Credentials} apply to. * * * @since 4.0 */ @Immutable public class AuthScope { /** * The null value represents any host. In the future versions of * HttpClient the use of this parameter will be discontinued. */ public static final String ANY_HOST = null; /** * The -1 value represents any port. */ public static final int ANY_PORT = -1; /** * The null value represents any realm. */ public static final String ANY_REALM = null; /** * The null value represents any authentication scheme. */ public static final String ANY_SCHEME = null; /** * Default scope matching any host, port, realm and authentication scheme. * In the future versions of HttpClient the use of this parameter will be * discontinued. */ public static final AuthScope ANY = new AuthScope(ANY_HOST, ANY_PORT, ANY_REALM, ANY_SCHEME); /** The authentication scheme the credentials apply to. */ private final String scheme; /** The realm the credentials apply to. */ private final String realm; /** The host the credentials apply to. */ private final String host; /** The port the credentials apply to. */ private final int port; /** Creates a new credentials scope for the given * host, port, realm, and * authentication scheme. * * @param host the host the credentials apply to. May be set * to null if credentials are applicable to * any host. * @param port the port the credentials apply to. May be set * to negative value if credentials are applicable to * any port. * @param realm the realm the credentials apply to. May be set * to null if credentials are applicable to * any realm. * @param scheme the authentication scheme the credentials apply to. * May be set to null if credentials are applicable to * any authentication scheme. */ public AuthScope(final String host, final int port, final String realm, final String scheme) { this.host = (host == null) ? ANY_HOST: host.toLowerCase(Locale.ENGLISH); this.port = (port < 0) ? ANY_PORT: port; this.realm = (realm == null) ? ANY_REALM: realm; this.scheme = (scheme == null) ? ANY_SCHEME: scheme.toUpperCase(Locale.ENGLISH); } /** * @since 4.2 */ public AuthScope(final HttpHost host, final String realm, final String schemeName) { this(host.getHostName(), host.getPort(), realm, schemeName); } /** * @since 4.2 */ public AuthScope(final HttpHost host) { this(host, ANY_REALM, ANY_SCHEME); } /** Creates a new credentials scope for the given * host, port, realm, and any * authentication scheme. * * @param host the host the credentials apply to. May be set * to null if credentials are applicable to * any host. * @param port the port the credentials apply to. May be set * to negative value if credentials are applicable to * any port. * @param realm the realm the credentials apply to. May be set * to null if credentials are applicable to * any realm. */ public AuthScope(final String host, final int port, final String realm) { this(host, port, realm, ANY_SCHEME); } /** Creates a new credentials scope for the given * host, port, any realm name, and any * authentication scheme. * * @param host the host the credentials apply to. May be set * to null if credentials are applicable to * any host. * @param port the port the credentials apply to. May be set * to negative value if credentials are applicable to * any port. */ public AuthScope(final String host, final int port) { this(host, port, ANY_REALM, ANY_SCHEME); } /** * Creates a copy of the given credentials scope. */ public AuthScope(final AuthScope authscope) { super(); Args.notNull(authscope, "Scope"); this.host = authscope.getHost(); this.port = authscope.getPort(); this.realm = authscope.getRealm(); this.scheme = authscope.getScheme(); } /** * @return the host */ public String getHost() { return this.host; } /** * @return the port */ public int getPort() { return this.port; } /** * @return the realm name */ public String getRealm() { return this.realm; } /** * @return the scheme type */ public String getScheme() { return this.scheme; } /** * Tests if the authentication scopes match. * * @return the match factor. Negative value signifies no match. * Non-negative signifies a match. The greater the returned value * the closer the match. */ public int match(final AuthScope that) { int factor = 0; if (LangUtils.equals(this.scheme, that.scheme)) { factor += 1; } else { if (this.scheme != ANY_SCHEME && that.scheme != ANY_SCHEME) { return -1; } } if (LangUtils.equals(this.realm, that.realm)) { factor += 2; } else { if (this.realm != ANY_REALM && that.realm != ANY_REALM) { return -1; } } if (this.port == that.port) { factor += 4; } else { if (this.port != ANY_PORT && that.port != ANY_PORT) { return -1; } } if (LangUtils.equals(this.host, that.host)) { factor += 8; } else { if (this.host != ANY_HOST && that.host != ANY_HOST) { return -1; } } return factor; } /** * @see java.lang.Object#equals(Object) */ @Override public boolean equals(final Object o) { if (o == null) { return false; } if (o == this) { return true; } if (!(o instanceof AuthScope)) { return super.equals(o); } final AuthScope that = (AuthScope) o; return LangUtils.equals(this.host, that.host) && this.port == that.port && LangUtils.equals(this.realm, that.realm) && LangUtils.equals(this.scheme, that.scheme); } /** * @see java.lang.Object#toString() */ @Override public String toString() { final StringBuilder buffer = new StringBuilder(); if (this.scheme != null) { buffer.append(this.scheme.toUpperCase(Locale.ENGLISH)); buffer.append(' '); } if (this.realm != null) { buffer.append('\''); buffer.append(this.realm); buffer.append('\''); } else { buffer.append(""); } if (this.host != null) { buffer.append('@'); buffer.append(this.host); if (this.port >= 0) { buffer.append(':'); buffer.append(this.port); } } return buffer.toString(); } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { int hash = LangUtils.HASH_SEED; hash = LangUtils.hashCode(hash, this.host); hash = LangUtils.hashCode(hash, this.port); hash = LangUtils.hashCode(hash, this.realm); hash = LangUtils.hashCode(hash, this.scheme); return hash; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/AuthState.java0100644 0000000 0000000 00000014464 12301751700 030125 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import java.util.Queue; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.util.Args; /** * This class provides detailed information about the state of the authentication process. * * @since 4.0 */ @NotThreadSafe public class AuthState { /** Actual state of authentication protocol */ private AuthProtocolState state; /** Actual authentication scheme */ private AuthScheme authScheme; /** Actual authentication scope */ private AuthScope authScope; /** Credentials selected for authentication */ private Credentials credentials; /** Available auth options */ private Queue authOptions; public AuthState() { super(); this.state = AuthProtocolState.UNCHALLENGED; } /** * Resets the auth state. * * @since 4.2 */ public void reset() { this.state = AuthProtocolState.UNCHALLENGED; this.authOptions = null; this.authScheme = null; this.authScope = null; this.credentials = null; } /** * @since 4.2 */ public AuthProtocolState getState() { return this.state; } /** * @since 4.2 */ public void setState(final AuthProtocolState state) { this.state = state != null ? state : AuthProtocolState.UNCHALLENGED; } /** * Returns actual {@link AuthScheme}. May be null. */ public AuthScheme getAuthScheme() { return this.authScheme; } /** * Returns actual {@link Credentials}. May be null. */ public Credentials getCredentials() { return this.credentials; } /** * Updates the auth state with {@link AuthScheme} and {@link Credentials}. * * @param authScheme auth scheme. May not be null. * @param credentials user crednetials. May not be null. * * @since 4.2 */ public void update(final AuthScheme authScheme, final Credentials credentials) { Args.notNull(authScheme, "Auth scheme"); Args.notNull(credentials, "Credentials"); this.authScheme = authScheme; this.credentials = credentials; this.authOptions = null; } /** * Returns available {@link AuthOption}s. May be null. * * @since 4.2 */ public Queue getAuthOptions() { return this.authOptions; } /** * Returns true if {@link AuthOption}s are available, false * otherwise. * * @since 4.2 */ public boolean hasAuthOptions() { return this.authOptions != null && !this.authOptions.isEmpty(); } /** * Updates the auth state with a queue of {@link AuthOption}s. * * @param authOptions a queue of auth options. May not be null or empty. * * @since 4.2 */ public void update(final Queue authOptions) { Args.notEmpty(authOptions, "Queue of auth options"); this.authOptions = authOptions; this.authScheme = null; this.credentials = null; } /** * Invalidates the authentication state by resetting its parameters. * * @deprecated (4.2) use {@link #reset()} */ @Deprecated public void invalidate() { reset(); } /** * @deprecated (4.2) do not use */ @Deprecated public boolean isValid() { return this.authScheme != null; } /** * Assigns the given {@link AuthScheme authentication scheme}. * * @param authScheme the {@link AuthScheme authentication scheme} * * @deprecated (4.2) use {@link #update(AuthScheme, Credentials)} */ @Deprecated public void setAuthScheme(final AuthScheme authScheme) { if (authScheme == null) { reset(); return; } this.authScheme = authScheme; } /** * Sets user {@link Credentials} to be used for authentication * * @param credentials User credentials * * @deprecated (4.2) use {@link #update(AuthScheme, Credentials)} */ @Deprecated public void setCredentials(final Credentials credentials) { this.credentials = credentials; } /** * Returns actual {@link AuthScope} if available * * @return actual authentication scope if available, null. * */ package org.apache.http.auth; import java.io.Serializable; import java.security.Principal; import org.apache.http.annotation.Immutable; import org.apache.http.util.Args; import org.apache.http.util.LangUtils; /** * Basic user principal used for HTTP authentication * * @since 4.0 */ @Immutable public final class BasicUserPrincipal implements Principal, Serializable { private static final long serialVersionUID = -2266305184969850467L; private final String username; public BasicUserPrincipal(final String username) { super(); Args.notNull(username, "User name"); this.username = username; } public String getName() { return this.username; } @Override public int hashCode() { int hash = LangUtils.HASH_SEED; hash = LangUtils.hashCode(hash, this.username); return hash; } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o instanceof BasicUserPrincipal) { final BasicUserPrincipal that = (BasicUserPrincipal) o; if (LangUtils.equals(this.username, that.username)) { return true; } } return false; } @Override public String toString() { final StringBuilder buffer = new StringBuilder(); buffer.append("[principal: "); buffer.append(this.username); buffer.append("]"); return buffer.toString(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/ChallengeState.java0100644 0000000 0000000 00000002457 12301751701 031106 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; /** * Challenge mode (TARGET or PROXY) * * @since 4.2 */ public enum ChallengeState { TARGET, PROXY } ././@LongLink0100644 0000000 0000000 00000000146 12302131604 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/ContextAwareAuthScheme.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/ContextAwareAuthScheme.jav0100644 0000000 0000000 00000004315 12301751701 032430 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.protocol.HttpContext; /** * This interface represents an extended authentication scheme * that requires access to {@link HttpContext} in order to * generate an authorization string. * * TODO: Fix AuthScheme interface in the next major version * * @since 4.1 */ public interface ContextAwareAuthScheme extends AuthScheme { /** * Produces an authorization string for the given set of * {@link Credentials}. * * @param credentials The set of credentials to be used for athentication * @param request The request being authenticated * @param context HTTP context * @throws AuthenticationException if authorization string cannot * be generated due to an authentication failure * * @return the authorization string */ Header authenticate( Credentials credentials, HttpRequest request, HttpContext context) throws AuthenticationException; } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/Credentials.java0100644 0000000 0000000 00000002770 12301751700 030455 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import java.security.Principal; /** * This interface represents a set of credentials consisting of a security * principal and a secret (password) that can be used to establish user * identity * * @since 4.0 */ public interface Credentials { Principal getUserPrincipal(); String getPassword(); } ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/InvalidCredentialsException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/InvalidCredentialsExceptio0100644 0000000 0000000 00000004554 12301751701 032550 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import org.apache.http.annotation.Immutable; /** * Authentication credentials required to respond to a authentication * challenge are invalid * * * @since 4.0 */ @Immutable public class InvalidCredentialsException extends AuthenticationException { private static final long serialVersionUID = -4834003835215460648L; /** * Creates a new InvalidCredentialsException with a null detail message. */ public InvalidCredentialsException() { super(); } /** * Creates a new InvalidCredentialsException with the specified message. * * @param message the exception detail message */ public InvalidCredentialsException(final String message) { super(message); } /** * Creates a new InvalidCredentialsException with the specified detail message and cause. * * @param message the exception detail message * @param cause the Throwable that caused this exception, or null * if the cause is unavailable, unknown, or not a Throwable */ public InvalidCredentialsException(final String message, final Throwable cause) { super(message, cause); } } ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/MalformedChallengeException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/MalformedChallengeExceptio0100644 0000000 0000000 00000004622 12301751700 032510 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import org.apache.http.ProtocolException; import org.apache.http.annotation.Immutable; /** * Signals that authentication challenge is in some way invalid or * illegal in the given context * * * @since 4.0 */ @Immutable public class MalformedChallengeException extends ProtocolException { private static final long serialVersionUID = 814586927989932284L; /** * Creates a new MalformedChallengeException with a null detail message. */ public MalformedChallengeException() { super(); } /** * Creates a new MalformedChallengeException with the specified message. * * @param message the exception detail message */ public MalformedChallengeException(final String message) { super(message); } /** * Creates a new MalformedChallengeException with the specified detail message and cause. * * @param message the exception detail message * @param cause the Throwable that caused this exception, or null * if the cause is unavailable, unknown, or not a Throwable */ public MalformedChallengeException(final String message, final Throwable cause) { super(message, cause); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/NTCredentials.java0100644 0000000 0000000 00000013302 12301751700 030710 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import java.io.Serializable; import java.security.Principal; import java.util.Locale; import org.apache.http.annotation.Immutable; import org.apache.http.util.Args; import org.apache.http.util.LangUtils; /** * {@link Credentials} implementation for Microsoft Windows platforms that includes * Windows specific attributes such as name of the domain the user belongs to. * * @since 4.0 */ @Immutable public class NTCredentials implements Credentials, Serializable { private static final long serialVersionUID = -7385699315228907265L; /** The user principal */ private final NTUserPrincipal principal; /** Password */ private final String password; /** The host the authentication request is originating from. */ private final String workstation; /** * The constructor with the fully qualified username and password combined * string argument. * * @param usernamePassword the domain/username:password formed string */ public NTCredentials(final String usernamePassword) { super(); Args.notNull(usernamePassword, "Username:password string"); final String username; final int atColon = usernamePassword.indexOf(':'); if (atColon >= 0) { username = usernamePassword.substring(0, atColon); this.password = usernamePassword.substring(atColon + 1); } else { username = usernamePassword; this.password = null; } final int atSlash = username.indexOf('/'); if (atSlash >= 0) { this.principal = new NTUserPrincipal( username.substring(0, atSlash).toUpperCase(Locale.ENGLISH), username.substring(atSlash + 1)); } else { this.principal = new NTUserPrincipal( null, username.substring(atSlash + 1)); } this.workstation = null; } /** * Constructor. * @param userName The user name. This should not include the domain to authenticate with. * For example: "user" is correct whereas "DOMAIN\\user" is not. * @param password The password. * @param workstation The workstation the authentication request is originating from. * Essentially, the computer name for this machine. * @param domain The domain to authenticate within. */ public NTCredentials( final String userName, final String password, final String workstation, final String domain) { super(); Args.notNull(userName, "User name"); this.principal = new NTUserPrincipal(domain, userName); this.password = password; if (workstation != null) { this.workstation = workstation.toUpperCase(Locale.ENGLISH); } else { this.workstation = null; } } public Principal getUserPrincipal() { return this.principal; } public String getUserName() { return this.principal.getUsername(); } public String getPassword() { return this.password; } /** * Retrieves the name to authenticate with. * * @return String the domain these credentials are intended to authenticate with. */ public String getDomain() { return this.principal.getDomain(); } /** * Retrieves the workstation name of the computer originating the request. * * @return String the workstation the user is logged into. */ public String getWorkstation() { return this.workstation; } @Override public int hashCode() { int hash = LangUtils.HASH_SEED; hash = LangUtils.hashCode(hash, this.principal); hash = LangUtils.hashCode(hash, this.workstation); return hash; } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o instanceof NTCredentials) { final NTCredentials that = (NTCredentials) o; if (LangUtils.equals(this.principal, that.principal) && LangUtils.equals(this.workstation, that.workstation)) { return true; } } return false; } @Override public String toString() { final StringBuilder buffer = new StringBuilder(); buffer.append("[principal: "); buffer.append(this.principal); buffer.append("][workstation: "); buffer.append(this.workstation); buffer.append("]"); return buffer.toString(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/NTUserPrincipal.java0100644 0000000 0000000 00000006520 12301751701 031240 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import java.io.Serializable; import java.security.Principal; import java.util.Locale; import org.apache.http.annotation.Immutable; import org.apache.http.util.Args; import org.apache.http.util.LangUtils; /** * Microsoft Windows specific user principal implementation. * * @since 4.0 */ @Immutable public class NTUserPrincipal implements Principal, Serializable { private static final long serialVersionUID = -6870169797924406894L; private final String username; private final String domain; private final String ntname; public NTUserPrincipal( final String domain, final String username) { super(); Args.notNull(username, "User name"); this.username = username; if (domain != null) { this.domain = domain.toUpperCase(Locale.ENGLISH); } else { this.domain = null; } if (this.domain != null && this.domain.length() > 0) { final StringBuilder buffer = new StringBuilder(); buffer.append(this.domain); buffer.append('\\'); buffer.append(this.username); this.ntname = buffer.toString(); } else { this.ntname = this.username; } } public String getName() { return this.ntname; } public String getDomain() { return this.domain; } public String getUsername() { return this.username; } @Override public int hashCode() { int hash = LangUtils.HASH_SEED; hash = LangUtils.hashCode(hash, this.username); hash = LangUtils.hashCode(hash, this.domain); return hash; } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o instanceof NTUserPrincipal) { final NTUserPrincipal that = (NTUserPrincipal) o; if (LangUtils.equals(this.username, that.username) && LangUtils.equals(this.domain, that.domain)) { return true; } } return false; } @Override public String toString() { return this.ntname; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/package-info.java0100644 0000000 0000000 00000002353 12301751700 030541 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Client HTTP authentication APIs. */ package org.apache.http.auth; ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/UsernamePasswordCredentials.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/UsernamePasswordCredential0100644 0000000 0000000 00000007217 12301751701 032577 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import java.io.Serializable; import java.security.Principal; import org.apache.http.annotation.Immutable; import org.apache.http.util.Args; import org.apache.http.util.LangUtils; /** * Simple {@link Credentials} implementation based on a user name / password * pair. * * @since 4.0 */ @Immutable public class UsernamePasswordCredentials implements Credentials, Serializable { private static final long serialVersionUID = 243343858802739403L; private final BasicUserPrincipal principal; private final String password; /** * The constructor with the username and password combined string argument. * * @param usernamePassword the username:password formed string * @see #toString */ public UsernamePasswordCredentials(final String usernamePassword) { super(); Args.notNull(usernamePassword, "Username:password string"); final int atColon = usernamePassword.indexOf(':'); if (atColon >= 0) { this.principal = new BasicUserPrincipal(usernamePassword.substring(0, atColon)); this.password = usernamePassword.substring(atColon + 1); } else { this.principal = new BasicUserPrincipal(usernamePassword); this.password = null; } } /** * The constructor with the username and password arguments. * * @param userName the user name * @param password the password */ public UsernamePasswordCredentials(final String userName, final String password) { super(); Args.notNull(userName, "Username"); this.principal = new BasicUserPrincipal(userName); this.password = password; } public Principal getUserPrincipal() { return this.principal; } public String getUserName() { return this.principal.getName(); } public String getPassword() { return password; } @Override public int hashCode() { return this.principal.hashCode(); } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o instanceof UsernamePasswordCredentials) { final UsernamePasswordCredentials that = (UsernamePasswordCredentials) o; if (LangUtils.equals(this.principal, that.principal)) { return true; } } return false; } @Override public String toString() { return this.principal.toString(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/params/0040755 0000000 0000000 00000000000 12301751700 026635 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/params/AuthPNames.java0100644 0000000 0000000 00000005466 12301751700 031515 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth.params; /** * Parameter names for HTTP authentication classes. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.client.config.RequestConfig} * and constructor parameters of * {@link org.apache.http.auth.AuthSchemeProvider}s. */ @Deprecated public interface AuthPNames { /** * Defines the charset to be used when encoding * {@link org.apache.http.auth.Credentials}. *

* This parameter expects a value of type {@link String}. */ public static final String CREDENTIAL_CHARSET = "http.auth.credential-charset"; /** * Defines the order of preference for supported * {@link org.apache.http.auth.AuthScheme}s when authenticating with * the target host. *

* This parameter expects a value of type {@link java.util.Collection}. The * collection is expected to contain {@link String} instances representing * a name of an authentication scheme as returned by * {@link org.apache.http.auth.AuthScheme#getSchemeName()}. */ public static final String TARGET_AUTH_PREF = "http.auth.target-scheme-pref"; /** * Defines the order of preference for supported * {@link org.apache.http.auth.AuthScheme}s when authenticating with the * proxy host. *

* This parameter expects a value of type {@link java.util.Collection}. The * collection is expected to contain {@link String} instances representing * a name of an authentication scheme as returned by * {@link org.apache.http.auth.AuthScheme#getSchemeName()}. */ public static final String PROXY_AUTH_PREF = "http.auth.proxy-scheme-pref"; } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/auth/params/package-info.java0100644 0000000 0000000 00000002363 12301751700 032025 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Deprecated. * @deprecated (4.3). */ package org.apache.http.auth.params; httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/0040755 0000000 0000000 00000000000 12301751677 025704 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/AuthCache.java0100644 0000000 0000000 00000003162 12301751677 030373 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScheme; /** * Abstract {@link AuthScheme} cache. Initialized {@link AuthScheme} objects * from this cache can be used to preemptively authenticate against known * hosts. * * @since 4.1 */ public interface AuthCache { void put(HttpHost host, AuthScheme authScheme); AuthScheme get(HttpHost host); void remove(HttpHost host); void clear(); } ././@LongLink0100644 0000000 0000000 00000000150 12302131604 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/AuthenticationStrategy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/AuthenticationStrategy.j0100644 0000000 0000000 00000011156 12301751674 032557 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import java.util.Map; import java.util.Queue; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.auth.AuthOption; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.protocol.HttpContext; /** /** * A handler for determining if an HTTP response represents an authentication challenge that was * sent back to the client as a result of authentication failure. *

* Implementations of this interface must be thread-safe. Access to shared data must be * synchronized as methods of this interface may be executed from multiple threads. * * @since 4.2 */ public interface AuthenticationStrategy { /** * Determines if the given HTTP response response represents * an authentication challenge that was sent back as a result * of authentication failure. * * @param authhost authentication host. * @param response HTTP response. * @param context HTTP context. * @return true if user authentication is required, * false otherwise. */ boolean isAuthenticationRequested( HttpHost authhost, HttpResponse response, HttpContext context); /** * Extracts from the given HTTP response a collection of authentication * challenges, each of which represents an authentication scheme supported * by the authentication host. * * @param authhost authentication host. * @param response HTTP response. * @param context HTTP context. * @return a collection of challenges keyed by names of corresponding * authentication schemes. * @throws MalformedChallengeException if one of the authentication * challenges is not valid or malformed. */ Map getChallenges( HttpHost authhost, HttpResponse response, HttpContext context) throws MalformedChallengeException; /** * Selects one authentication challenge out of all available and * creates and generates {@link AuthOption} instance capable of * processing that challenge. * * @param challenges collection of challenges. * @param authhost authentication host. * @param response HTTP response. * @param context HTTP context. * @return authentication auth schemes that can be used for authentication. Can be empty. * @throws MalformedChallengeException if one of the authentication * challenges is not valid or malformed. */ Queue select( Map challenges, HttpHost authhost, HttpResponse response, HttpContext context) throws MalformedChallengeException; /** * Callback invoked in case of successful authentication. * * @param authhost authentication host. * @param authScheme authentication scheme used. * @param context HTTP context. */ void authSucceeded( HttpHost authhost, AuthScheme authScheme, HttpContext context); /** * Callback invoked in case of unsuccessful authentication. * * @param authhost authentication host. * @param authScheme authentication scheme used. * @param context HTTP context. */ void authFailed( HttpHost authhost, AuthScheme authScheme, HttpContext context); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/BackoffManager.java0100644 0000000 0000000 00000003514 12301751677 031375 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import org.apache.http.conn.routing.HttpRoute; /** * Represents a controller that dynamically adjusts the size * of an available connection pool based on feedback from * using the connections. * * @since 4.2 * */ public interface BackoffManager { /** * Called when we have decided that the result of * using a connection should be interpreted as a * backoff signal. */ public void backOff(HttpRoute route); /** * Called when we have determined that the result of * using a connection has succeeded and that we may * probe for more connections. */ public void probe(HttpRoute route); } ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/CircularRedirectException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/CircularRedirectExceptio0100644 0000000 0000000 00000004440 12301751675 032553 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import org.apache.http.annotation.Immutable; /** * Signals a circular redirect * * * @since 4.0 */ @Immutable public class CircularRedirectException extends RedirectException { private static final long serialVersionUID = 6830063487001091803L; /** * Creates a new CircularRedirectException with a null detail message. */ public CircularRedirectException() { super(); } /** * Creates a new CircularRedirectException with the specified detail message. * * @param message The exception detail message */ public CircularRedirectException(final String message) { super(message); } /** * Creates a new CircularRedirectException with the specified detail message and cause. * * @param message the exception detail message * @param cause the Throwable that caused this exception, or null * if the cause is unavailable, unknown, or not a Throwable */ public CircularRedirectException(final String message, final Throwable cause) { super(message, cause); } } ././@LongLink0100644 0000000 0000000 00000000151 12302131604 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/ClientProtocolException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/ClientProtocolException.0100644 0000000 0000000 00000003527 12301751675 032526 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import java.io.IOException; import org.apache.http.annotation.Immutable; /** * Signals an error in the HTTP protocol. * * @since 4.0 */ @Immutable public class ClientProtocolException extends IOException { private static final long serialVersionUID = -5596590843227115865L; public ClientProtocolException() { super(); } public ClientProtocolException(final String s) { super(s); } public ClientProtocolException(final Throwable cause) { initCause(cause); } public ClientProtocolException(final String message, final Throwable cause) { super(message); initCause(cause); } } ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/ConnectionBackoffStrategy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/ConnectionBackoffStrateg0100644 0000000 0000000 00000004673 12301751674 032540 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import org.apache.http.HttpResponse; /** * When managing a dynamic number of connections for a given route, this * strategy assesses whether a given request execution outcome should * result in a backoff signal or not, based on either examining the * Throwable that resulted or by examining the resulting * response (e.g. for its status code). * * @since 4.2 * */ public interface ConnectionBackoffStrategy { /** * Determines whether seeing the given Throwable as * a result of request execution should result in a backoff * signal. * @param t the Throwable that happened * @return true if a backoff signal should be * given */ boolean shouldBackoff(Throwable t); /** * Determines whether receiving the given {@link HttpResponse} as * a result of request execution should result in a backoff * signal. Implementations MUST restrict themselves to examining * the response header and MUST NOT consume any of the response * body, if any. * @param resp the HttpResponse that was received * @return true if a backoff signal should be * given */ boolean shouldBackoff(HttpResponse resp); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/CookieStore.java0100644 0000000 0000000 00000004176 12301751677 031002 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import java.util.Date; import java.util.List; import org.apache.http.cookie.Cookie; /** * This interface represents an abstract store for {@link Cookie} * objects. * * @since 4.0 */ public interface CookieStore { /** * Adds an {@link Cookie}, replacing any existing equivalent cookies. * If the given cookie has already expired it will not be added, but existing * values will still be removed. * * @param cookie the {@link Cookie cookie} to be added */ void addCookie(Cookie cookie); /** * Returns all cookies contained in this store. * * @return all cookies */ List getCookies(); /** * Removes all of {@link Cookie}s in this store that have expired by * the specified {@link java.util.Date}. * * @return true if any cookies were purged. */ boolean clearExpired(Date date); /** * Clears all cookies. */ void clear(); } ././@LongLink0100644 0000000 0000000 00000000145 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/CredentialsProvider.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/CredentialsProvider.java0100644 0000000 0000000 00000004665 12301751675 032525 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; /** * Abstract credentials provider that maintains a collection of user * credentials. *

* Implementations of this interface must be thread-safe. Access to shared * data must be synchronized as methods of this interface may be executed * from multiple threads. * * @since 4.0 */ public interface CredentialsProvider { /** * Sets the {@link Credentials credentials} for the given authentication * scope. Any previous credentials for the given scope will be overwritten. * * @param authscope the {@link AuthScope authentication scope} * @param credentials the authentication {@link Credentials credentials} * for the given scope. * * @see #getCredentials(AuthScope) */ void setCredentials(AuthScope authscope, Credentials credentials); /** * Get the {@link Credentials credentials} for the given authentication scope. * * @param authscope the {@link AuthScope authentication scope} * @return the credentials * * @see #setCredentials(AuthScope, Credentials) */ Credentials getCredentials(AuthScope authscope); /** * Clears all credentials. */ void clear(); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/HttpClient.java0100644 0000000 0000000 00000026336 12301751675 030632 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; import java.io.IOException; /** * This interface represents only the most basic contract for HTTP request * execution. It imposes no restrictions or particular details on the request * execution process and leaves the specifics of state management, * authentication and redirect handling up to individual implementations. * * @since 4.0 */ @SuppressWarnings("deprecation") public interface HttpClient { /** * Obtains the parameters for this client. * These parameters will become defaults for all requests being * executed with this client, and for the parameters of * dependent objects in this client. * * @return the default parameters * * @deprecated (4.3) use * {@link org.apache.http.client.config.RequestConfig}. */ @Deprecated HttpParams getParams(); /** * Obtains the connection manager used by this client. * * @return the connection manager * * @deprecated (4.3) use * {@link org.apache.http.impl.client.HttpClientBuilder}. */ @Deprecated ClientConnectionManager getConnectionManager(); /** * Executes HTTP request using the default context. * * @param request the request to execute * * @return the response to the request. This is always a final response, * never an intermediate response with an 1xx status code. * Whether redirects or authentication challenges will be returned * or handled automatically depends on the implementation and * configuration of this client. * @throws IOException in case of a problem or the connection was aborted * @throws ClientProtocolException in case of an http protocol error */ HttpResponse execute(HttpUriRequest request) throws IOException, ClientProtocolException; /** * Executes HTTP request using the given context. * * @param request the request to execute * @param context the context to use for the execution, or * null to use the default context * * @return the response to the request. This is always a final response, * never an intermediate response with an 1xx status code. * Whether redirects or authentication challenges will be returned * or handled automatically depends on the implementation and * configuration of this client. * @throws IOException in case of a problem or the connection was aborted * @throws ClientProtocolException in case of an http protocol error */ HttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException, ClientProtocolException; /** * Executes HTTP request using the default context. * * @param target the target host for the request. * Implementations may accept null * if they can still determine a route, for example * to a default target or by inspecting the request. * @param request the request to execute * * @return the response to the request. This is always a final response, * never an intermediate response with an 1xx status code. * Whether redirects or authentication challenges will be returned * or handled automatically depends on the implementation and * configuration of this client. * @throws IOException in case of a problem or the connection was aborted * @throws ClientProtocolException in case of an http protocol error */ HttpResponse execute(HttpHost target, HttpRequest request) throws IOException, ClientProtocolException; /** * Executes HTTP request using the given context. * * @param target the target host for the request. * Implementations may accept null * if they can still determine a route, for example * to a default target or by inspecting the request. * @param request the request to execute * @param context the context to use for the execution, or * null to use the default context * * @return the response to the request. This is always a final response, * never an intermediate response with an 1xx status code. * Whether redirects or authentication challenges will be returned * or handled automatically depends on the implementation and * configuration of this client. * @throws IOException in case of a problem or the connection was aborted * @throws ClientProtocolException in case of an http protocol error */ HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws IOException, ClientProtocolException; /** * Executes HTTP request using the default context and processes the * response using the given response handler. *

* Implementing classes are required to ensure that the content entity * associated with the response is fully consumed and the underlying * connection is released back to the connection manager automatically * in all cases relieving individual {@link ResponseHandler}s from * having to manage resource deallocation internally. * * @param request the request to execute * @param responseHandler the response handler * * @return the response object as generated by the response handler. * @throws IOException in case of a problem or the connection was aborted * @throws ClientProtocolException in case of an http protocol error */ T execute( HttpUriRequest request, ResponseHandler responseHandler) throws IOException, ClientProtocolException; /** * Executes HTTP request using the given context and processes the * response using the given response handler. *

* Implementing classes are required to ensure that the content entity * associated with the response is fully consumed and the underlying * connection is released back to the connection manager automatically * in all cases relieving individual {@link ResponseHandler}s from * having to manage resource deallocation internally. * * @param request the request to execute * @param responseHandler the response handler * @param context the context to use for the execution, or * null to use the default context * * @return the response object as generated by the response handler. * @throws IOException in case of a problem or the connection was aborted * @throws ClientProtocolException in case of an http protocol error */ T execute( HttpUriRequest request, ResponseHandler responseHandler, HttpContext context) throws IOException, ClientProtocolException; /** * Executes HTTP request to the target using the default context and * processes the response using the given response handler. *

* Implementing classes are required to ensure that the content entity * associated with the response is fully consumed and the underlying * connection is released back to the connection manager automatically * in all cases relieving individual {@link ResponseHandler}s from * having to manage resource deallocation internally. * * @param target the target host for the request. * Implementations may accept null * if they can still determine a route, for example * to a default target or by inspecting the request. * @param request the request to execute * @param responseHandler the response handler * * @return the response object as generated by the response handler. * @throws IOException in case of a problem or the connection was aborted * @throws ClientProtocolException in case of an http protocol error */ T execute( HttpHost target, HttpRequest request, ResponseHandler responseHandler) throws IOException, ClientProtocolException; /** * Executes HTTP request to the target using the given context and * processes the response using the given response handler. *

* Implementing classes are required to ensure that the content entity * associated with the response is fully consumed and the underlying * connection is released back to the connection manager automatically * in all cases relieving individual {@link ResponseHandler}s from * having to manage resource deallocation internally. * * @param target the target host for the request. * Implementations may accept null * if they can still determine a route, for example * to a default target or by inspecting the request. * @param request the request to execute * @param responseHandler the response handler * @param context the context to use for the execution, or * null to use the default context * * @return the response object as generated by the response handler. * @throws IOException in case of a problem or the connection was aborted * @throws ClientProtocolException in case of an http protocol error */ T execute( HttpHost target, HttpRequest request, ResponseHandler responseHandler, HttpContext context) throws IOException, ClientProtocolException; } ././@LongLink0100644 0000000 0000000 00000000151 12302131604 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/HttpRequestRetryHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/HttpRequestRetryHandler.0100644 0000000 0000000 00000004227 12301751675 032521 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import java.io.IOException; import org.apache.http.protocol.HttpContext; /** * A handler for determining if an HttpRequest should be retried after a * recoverable exception during execution. *

* Implementations of this interface must be thread-safe. Access to shared * data must be synchronized as methods of this interface may be executed * from multiple threads. * * @since 4.0 */ public interface HttpRequestRetryHandler { /** * Determines if a method should be retried after an IOException * occurs during execution. * * @param exception the exception that occurred * @param executionCount the number of times this method has been * unsuccessfully executed * @param context the context for the request execution * * @return true if the method should be retried, false * otherwise */ boolean retryRequest(IOException exception, int executionCount, HttpContext context); } ././@LongLink0100644 0000000 0000000 00000000147 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/HttpResponseException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/HttpResponseException.ja0100644 0000000 0000000 00000003273 12301751675 032535 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import org.apache.http.annotation.Immutable; /** * Signals a non 2xx HTTP response. * * @since 4.0 */ @Immutable public class HttpResponseException extends ClientProtocolException { private static final long serialVersionUID = -7186627969477257933L; private final int statusCode; public HttpResponseException(final int statusCode, final String s) { super(s); this.statusCode = statusCode; } public int getStatusCode() { return this.statusCode; } } ././@LongLink0100644 0000000 0000000 00000000157 12302131604 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/NonRepeatableRequestException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/NonRepeatableRequestExce0100644 0000000 0000000 00000004411 12301751675 032517 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import org.apache.http.ProtocolException; import org.apache.http.annotation.Immutable; /** * Signals failure to retry the request due to non-repeatable request * entity. * * * @since 4.0 */ @Immutable public class NonRepeatableRequestException extends ProtocolException { private static final long serialVersionUID = 82685265288806048L; /** * Creates a new NonRepeatableEntityException with a null detail message. */ public NonRepeatableRequestException() { super(); } /** * Creates a new NonRepeatableEntityException with the specified detail message. * * @param message The exception detail message */ public NonRepeatableRequestException(final String message) { super(message); } /** * Creates a new NonRepeatableEntityException with the specified detail message. * * @param message The exception detail message * @param cause the cause */ public NonRepeatableRequestException(final String message, final Throwable cause) { super(message, cause); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/package-info.java0100644 0000000 0000000 00000002354 12301751677 031074 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Client HTTP communication APIs. */ package org.apache.http.client; httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/RedirectException.java0100644 0000000 0000000 00000004474 12301751675 032173 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import org.apache.http.ProtocolException; import org.apache.http.annotation.Immutable; /** * Signals violation of HTTP specification caused by an invalid redirect * * * @since 4.0 */ @Immutable public class RedirectException extends ProtocolException { private static final long serialVersionUID = 4418824536372559326L; /** * Creates a new RedirectException with a null detail message. */ public RedirectException() { super(); } /** * Creates a new RedirectException with the specified detail message. * * @param message The exception detail message */ public RedirectException(final String message) { super(message); } /** * Creates a new RedirectException with the specified detail message and cause. * * @param message the exception detail message * @param cause the Throwable that caused this exception, or null * if the cause is unavailable, unknown, or not a Throwable */ public RedirectException(final String message, final Throwable cause) { super(message, cause); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/RedirectStrategy.java0100644 0000000 0000000 00000005700 12301751677 032032 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.ProtocolException; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.protocol.HttpContext; /** * A strategy for determining if an HTTP request should be redirected to * a new location in response to an HTTP response received from the target * server. *

* Implementations of this interface must be thread-safe. Access to shared * data must be synchronized as methods of this interface may be executed * from multiple threads. * * @since 4.1 */ public interface RedirectStrategy { /** * Determines if a request should be redirected to a new location * given the response from the target server. * * @param request the executed request * @param response the response received from the target server * @param context the context for the request execution * * @return true if the request should be redirected, false * otherwise */ boolean isRedirected( HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException; /** * Determines the redirect location given the response from the target * server and the current request execution context and generates a new * request to be sent to the location. * * @param request the executed request * @param response the response received from the target server * @param context the context for the request execution * * @return redirected request */ HttpUriRequest getRedirect( HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException; } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/ResponseHandler.java0100644 0000000 0000000 00000003611 12301751674 031636 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import java.io.IOException; import org.apache.http.HttpResponse; /** * Handler that encapsulates the process of generating a response object * from a {@link HttpResponse}. * * * @since 4.0 */ public interface ResponseHandler { /** * Processes an {@link HttpResponse} and returns some value * corresponding to that response. * * @param response The response to process * @return A value determined by the response * * @throws ClientProtocolException in case of an http protocol error * @throws IOException in case of a problem or the connection was aborted */ T handleResponse(HttpResponse response) throws ClientProtocolException, IOException; } ././@LongLink0100644 0000000 0000000 00000000161 12302131604 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/ServiceUnavailableRetryStrategy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/ServiceUnavailableRetryS0100644 0000000 0000000 00000004237 12301751675 032545 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import org.apache.http.HttpResponse; import org.apache.http.protocol.HttpContext; /** * Strategy interface that allows API users to plug in their own logic to * control whether or not a retry should automatically be done, how many times * it should be retried and so on. * * @since 4.2 */ public interface ServiceUnavailableRetryStrategy { /** * Determines if a method should be retried given the response from the target server. * * @param response the response from the target server * @param executionCount the number of times this method has been * unsuccessfully executed * @param context the context for the request execution * @return true if the method should be retried, false * otherwise */ boolean retryRequest(HttpResponse response, int executionCount, HttpContext context); /** * @return The interval between the subsequent auto-retries. */ long getRetryInterval(); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/UserTokenHandler.java0100644 0000000 0000000 00000004261 12301751675 031762 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import org.apache.http.protocol.HttpContext; /** * A handler for determining if the given execution context is user specific * or not. The token object returned by this handler is expected to uniquely * identify the current user if the context is user specific or to be * null if the context does not contain any resources or details * specific to the current user. *

* The user token will be used to ensure that user specific resources will not * be shared with or reused by other users. * * @since 4.0 */ public interface UserTokenHandler { /** * The token object returned by this method is expected to uniquely * identify the current user if the context is user specific or to be * null if it is not. * * @param context the execution context * * @return user token that uniquely identifies the user or * null if the context is not user specific. */ Object getUserToken(HttpContext context); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/config/0040755 0000000 0000000 00000000000 12301751677 027151 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/config/AuthSchemes.java0100644 0000000 0000000 00000004246 12301751677 032230 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.config; import org.apache.http.annotation.Immutable; /** * Standard authentication schemes supported by HttpClient. * * @since 4.3 */ @Immutable public final class AuthSchemes { /** * Basic authentication scheme as defined in RFC2617 (considered inherently * insecure, but most widely supported) */ public static final String BASIC = "Basic"; /** * Digest authentication scheme as defined in RFC2617. */ public static final String DIGEST = "Digest"; /** * The NTLM scheme is a proprietary Microsoft Windows Authentication * protocol (considered to be the most secure among currently supported * authentication schemes). */ public static final String NTLM = "NTLM"; /** * SPNEGO Authentication scheme. */ public static final String SPNEGO = "negotiate"; /** * Kerberos Authentication scheme. */ public static final String KERBEROS = "Kerberos"; private AuthSchemes() { } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/config/CookieSpecs.java0100644 0000000 0000000 00000004117 12301751677 032223 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.config; import org.apache.http.annotation.Immutable; /** * Standard cookie specifications supported by HttpClient. * * @since 4.3 */ @Immutable public final class CookieSpecs { /** * The policy that provides high degree of compatibility * with common cookie management of popular HTTP agents. */ public static final String BROWSER_COMPATIBILITY = "compatibility"; /** * The Netscape cookie draft compliant policy. */ public static final String NETSCAPE = "netscape"; /** * The RFC 2965 compliant policy (standard). */ public static final String STANDARD = "standard"; /** * The default 'best match' policy. */ public static final String BEST_MATCH = "best-match"; /** * The policy that ignores cookies. */ public static final String IGNORE_COOKIES = "ignoreCookies"; private CookieSpecs() { } } ././@LongLink0100644 0000000 0000000 00000000145 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/config/package-info.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/config/package-info.java0100644 0000000 0000000 00000002356 12301751677 032343 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Client configuration APIs. */ package org.apache.http.client.config; ././@LongLink0100644 0000000 0000000 00000000146 12302131604 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/config/RequestConfig.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/config/RequestConfig.jav0100644 0000000 0000000 00000040212 12301751677 032425 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.config; import java.net.InetAddress; import java.util.Collection; import org.apache.http.HttpHost; public class RequestConfig implements Cloneable { public static final RequestConfig DEFAULT = new Builder().build(); private final boolean expectContinueEnabled; private final HttpHost proxy; private final InetAddress localAddress; private final boolean staleConnectionCheckEnabled; private final String cookieSpec; private final boolean redirectsEnabled; private final boolean relativeRedirectsAllowed; private final boolean circularRedirectsAllowed; private final int maxRedirects; private final boolean authenticationEnabled; private final Collection targetPreferredAuthSchemes; private final Collection proxyPreferredAuthSchemes; private final int connectionRequestTimeout; private final int connectTimeout; private final int socketTimeout; RequestConfig( final boolean expectContinueEnabled, final HttpHost proxy, final InetAddress localAddress, final boolean staleConnectionCheckEnabled, final String cookieSpec, final boolean redirectsEnabled, final boolean relativeRedirectsAllowed, final boolean circularRedirectsAllowed, final int maxRedirects, final boolean authenticationEnabled, final Collection targetPreferredAuthSchemes, final Collection proxyPreferredAuthSchemes, final int connectionRequestTimeout, final int connectTimeout, final int socketTimeout) { super(); this.expectContinueEnabled = expectContinueEnabled; this.proxy = proxy; this.localAddress = localAddress; this.staleConnectionCheckEnabled = staleConnectionCheckEnabled; this.cookieSpec = cookieSpec; this.redirectsEnabled = redirectsEnabled; this.relativeRedirectsAllowed = relativeRedirectsAllowed; this.circularRedirectsAllowed = circularRedirectsAllowed; this.maxRedirects = maxRedirects; this.authenticationEnabled = authenticationEnabled; this.targetPreferredAuthSchemes = targetPreferredAuthSchemes; this.proxyPreferredAuthSchemes = proxyPreferredAuthSchemes; this.connectionRequestTimeout = connectionRequestTimeout; this.connectTimeout = connectTimeout; this.socketTimeout = socketTimeout; } /** * Determines whether the 'Expect: 100-Continue' handshake is enabled * for entity enclosing methods. The purpose of the 'Expect: 100-Continue' * handshake is to allow a client that is sending a request message with * a request body to determine if the origin server is willing to * accept the request (based on the request headers) before the client * sends the request body. *

* The use of the 'Expect: 100-continue' handshake can result in * a noticeable performance improvement for entity enclosing requests * (such as POST and PUT) that require the target server's * authentication. *

* 'Expect: 100-continue' handshake should be used with caution, as it * may cause problems with HTTP servers and proxies that do not support * HTTP/1.1 protocol. *

* Default: false */ public boolean isExpectContinueEnabled() { return expectContinueEnabled; } /** * Returns HTTP proxy to be used for request execution. *

* Default: null */ public HttpHost getProxy() { return proxy; } /** * Returns local address to be used for request execution. *

* On machines with multiple network interfaces, this parameter * can be used to select the network interface from which the * connection originates. *

* Default: null */ public InetAddress getLocalAddress() { return localAddress; } /** * Determines whether stale connection check is to be used. The stale * connection check can cause up to 30 millisecond overhead per request and * should be used only when appropriate. For performance critical * operations this check should be disabled. *

* Default: true */ public boolean isStaleConnectionCheckEnabled() { return staleConnectionCheckEnabled; } /** * Determines the name of the cookie specification to be used for HTTP state * management. *

* Default: null */ public String getCookieSpec() { return cookieSpec; } /** * Determines whether redirects should be handled automatically. *

* Default: true */ public boolean isRedirectsEnabled() { return redirectsEnabled; } /** * Determines whether relative redirects should be rejected. HTTP specification * requires the location value be an absolute URI. *

* Default: true */ public boolean isRelativeRedirectsAllowed() { return relativeRedirectsAllowed; } /** * Determines whether circular redirects (redirects to the same location) should * be allowed. The HTTP spec is not sufficiently clear whether circular redirects * are permitted, therefore optionally they can be enabled *

* Default: false */ public boolean isCircularRedirectsAllowed() { return circularRedirectsAllowed; } /** * Returns the maximum number of redirects to be followed. The limit on number * of redirects is intended to prevent infinite loops. *

* Default: 50 */ public int getMaxRedirects() { return maxRedirects; } /** * Determines whether authentication should be handled automatically. *

* Default: true */ public boolean isAuthenticationEnabled() { return authenticationEnabled; } /** * Determines the order of preference for supported authentication schemes * when authenticating with the target host. *

* Default: null */ public Collection getTargetPreferredAuthSchemes() { return targetPreferredAuthSchemes; } /** * Determines the order of preference for supported authentication schemes * when authenticating with the proxy host. *

* Default: null */ public Collection getProxyPreferredAuthSchemes() { return proxyPreferredAuthSchemes; } /** * Returns the timeout in milliseconds used when requesting a connection * from the connection manager. A timeout value of zero is interpreted * as an infinite timeout. *

* A timeout value of zero is interpreted as an infinite timeout. * A negative value is interpreted as undefined (system default). *

* Default: -1 */ public int getConnectionRequestTimeout() { return connectionRequestTimeout; } /** * Determines the timeout in milliseconds until a connection is established. * A timeout value of zero is interpreted as an infinite timeout. *

* A timeout value of zero is interpreted as an infinite timeout. * A negative value is interpreted as undefined (system default). *

* Default: -1 */ public int getConnectTimeout() { return connectTimeout; } /** * Defines the socket timeout (SO_TIMEOUT) in milliseconds, * which is the timeout for waiting for data or, put differently, * a maximum period inactivity between two consecutive data packets). *

* A timeout value of zero is interpreted as an infinite timeout. * A negative value is interpreted as undefined (system default). *

* Default: -1 */ public int getSocketTimeout() { return socketTimeout; } @Override protected RequestConfig clone() throws CloneNotSupportedException { return (RequestConfig) super.clone(); } @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append(", expectContinueEnabled=").append(expectContinueEnabled); builder.append(", proxy=").append(proxy); builder.append(", localAddress=").append(localAddress); builder.append(", staleConnectionCheckEnabled=").append(staleConnectionCheckEnabled); builder.append(", cookieSpec=").append(cookieSpec); builder.append(", redirectsEnabled=").append(redirectsEnabled); builder.append(", relativeRedirectsAllowed=").append(relativeRedirectsAllowed); builder.append(", maxRedirects=").append(maxRedirects); builder.append(", circularRedirectsAllowed=").append(circularRedirectsAllowed); builder.append(", authenticationEnabled=").append(authenticationEnabled); builder.append(", targetPreferredAuthSchemes=").append(targetPreferredAuthSchemes); builder.append(", proxyPreferredAuthSchemes=").append(proxyPreferredAuthSchemes); builder.append(", connectionRequestTimeout=").append(connectionRequestTimeout); builder.append(", connectTimeout=").append(connectTimeout); builder.append(", socketTimeout=").append(socketTimeout); builder.append("]"); return builder.toString(); } public static RequestConfig.Builder custom() { return new Builder(); } public static RequestConfig.Builder copy(final RequestConfig config) { return new Builder() .setExpectContinueEnabled(config.isExpectContinueEnabled()) .setProxy(config.getProxy()) .setLocalAddress(config.getLocalAddress()) .setStaleConnectionCheckEnabled(config.isStaleConnectionCheckEnabled()) .setCookieSpec(config.getCookieSpec()) .setRedirectsEnabled(config.isRedirectsEnabled()) .setRelativeRedirectsAllowed(config.isRelativeRedirectsAllowed()) .setCircularRedirectsAllowed(config.isCircularRedirectsAllowed()) .setMaxRedirects(config.getMaxRedirects()) .setAuthenticationEnabled(config.isAuthenticationEnabled()) .setTargetPreferredAuthSchemes(config.getTargetPreferredAuthSchemes()) .setProxyPreferredAuthSchemes(config.getProxyPreferredAuthSchemes()) .setConnectionRequestTimeout(config.getConnectionRequestTimeout()) .setConnectTimeout(config.getConnectTimeout()) .setSocketTimeout(config.getSocketTimeout()); } public static class Builder { private boolean expectContinueEnabled; private HttpHost proxy; private InetAddress localAddress; private boolean staleConnectionCheckEnabled; private String cookieSpec; private boolean redirectsEnabled; private boolean relativeRedirectsAllowed; private boolean circularRedirectsAllowed; private int maxRedirects; private boolean authenticationEnabled; private Collection targetPreferredAuthSchemes; private Collection proxyPreferredAuthSchemes; private int connectionRequestTimeout; private int connectTimeout; private int socketTimeout; Builder() { super(); this.staleConnectionCheckEnabled = true; this.redirectsEnabled = true; this.maxRedirects = 50; this.relativeRedirectsAllowed = true; this.authenticationEnabled = true; this.connectionRequestTimeout = -1; this.connectTimeout = -1; this.socketTimeout = -1; } public Builder setExpectContinueEnabled(final boolean expectContinueEnabled) { this.expectContinueEnabled = expectContinueEnabled; return this; } public Builder setProxy(final HttpHost proxy) { this.proxy = proxy; return this; } public Builder setLocalAddress(final InetAddress localAddress) { this.localAddress = localAddress; return this; } public Builder setStaleConnectionCheckEnabled(final boolean staleConnectionCheckEnabled) { this.staleConnectionCheckEnabled = staleConnectionCheckEnabled; return this; } public Builder setCookieSpec(final String cookieSpec) { this.cookieSpec = cookieSpec; return this; } public Builder setRedirectsEnabled(final boolean redirectsEnabled) { this.redirectsEnabled = redirectsEnabled; return this; } public Builder setRelativeRedirectsAllowed(final boolean relativeRedirectsAllowed) { this.relativeRedirectsAllowed = relativeRedirectsAllowed; return this; } public Builder setCircularRedirectsAllowed(final boolean circularRedirectsAllowed) { this.circularRedirectsAllowed = circularRedirectsAllowed; return this; } public Builder setMaxRedirects(final int maxRedirects) { this.maxRedirects = maxRedirects; return this; } public Builder setAuthenticationEnabled(final boolean authenticationEnabled) { this.authenticationEnabled = authenticationEnabled; return this; } public Builder setTargetPreferredAuthSchemes(final Collection targetPreferredAuthSchemes) { this.targetPreferredAuthSchemes = targetPreferredAuthSchemes; return this; } public Builder setProxyPreferredAuthSchemes(final Collection proxyPreferredAuthSchemes) { this.proxyPreferredAuthSchemes = proxyPreferredAuthSchemes; return this; } public Builder setConnectionRequestTimeout(final int connectionRequestTimeout) { this.connectionRequestTimeout = connectionRequestTimeout; return this; } public Builder setConnectTimeout(final int connectTimeout) { this.connectTimeout = connectTimeout; return this; } public Builder setSocketTimeout(final int socketTimeout) { this.socketTimeout = socketTimeout; return this; } public RequestConfig build() { return new RequestConfig( expectContinueEnabled, proxy, localAddress, staleConnectionCheckEnabled, cookieSpec, redirectsEnabled, relativeRedirectsAllowed, circularRedirectsAllowed, maxRedirects, authenticationEnabled, targetPreferredAuthSchemes, proxyPreferredAuthSchemes, connectionRequestTimeout, connectTimeout, socketTimeout); } } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/0040755 0000000 0000000 00000000000 12301751674 027215 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000154 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/DecompressingEntity.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/DecompressingEnti0100644 0000000 0000000 00000006317 12301751674 032566 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.entity; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.http.HttpEntity; import org.apache.http.entity.HttpEntityWrapper; import org.apache.http.util.Args; /** * Common base class for decompressing {@link HttpEntity} implementations. * * @since 4.1 */ abstract class DecompressingEntity extends HttpEntityWrapper { /** * Default buffer size. */ private static final int BUFFER_SIZE = 1024 * 2; /** * {@link #getContent()} method must return the same {@link InputStream} * instance when DecompressingEntity is wrapping a streaming entity. */ private InputStream content; /** * Creates a new {@link DecompressingEntity}. * * @param wrapped * the non-null {@link HttpEntity} to be wrapped */ public DecompressingEntity(final HttpEntity wrapped) { super(wrapped); } abstract InputStream decorate(final InputStream wrapped) throws IOException; private InputStream getDecompressingStream() throws IOException { final InputStream in = wrappedEntity.getContent(); return new LazyDecompressingInputStream(in, this); } /** * {@inheritDoc} */ @Override public InputStream getContent() throws IOException { if (wrappedEntity.isStreaming()) { if (content == null) { content = getDecompressingStream(); } return content; } else { return getDecompressingStream(); } } /** * {@inheritDoc} */ @Override public void writeTo(final OutputStream outstream) throws IOException { Args.notNull(outstream, "Output stream"); final InputStream instream = getContent(); try { final byte[] buffer = new byte[BUFFER_SIZE]; int l; while ((l = instream.read(buffer)) != -1) { outstream.write(buffer, 0, l); } } finally { instream.close(); } } } ././@LongLink0100644 0000000 0000000 00000000163 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/DeflateDecompressingEntity.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/DeflateDecompress0100644 0000000 0000000 00000006160 12301751674 032531 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.entity; import java.io.IOException; import java.io.InputStream; import org.apache.http.Header; import org.apache.http.HttpEntity; /** * {@link org.apache.http.entity.HttpEntityWrapper} responsible for handling * deflate Content Coded responses. In RFC2616 terms, deflate * means a zlib stream as defined in RFC1950. Some server * implementations have misinterpreted RFC2616 to mean that a * deflate stream as defined in RFC1951 should be used * (or maybe they did that since that's how IE behaves?). It's confusing * that deflate in HTTP 1.1 means zlib streams * rather than deflate streams. We handle both types in here, * since that's what is seen on the internet. Moral - prefer * gzip! * * @see GzipDecompressingEntity * * @since 4.1 */ public class DeflateDecompressingEntity extends DecompressingEntity { /** * Creates a new {@link DeflateDecompressingEntity} which will wrap the specified * {@link HttpEntity}. * * @param entity * a non-null {@link HttpEntity} to be wrapped */ public DeflateDecompressingEntity(final HttpEntity entity) { super(entity); } /** * Returns the non-null InputStream that should be returned to by all requests to * {@link #getContent()}. * * @return a non-null InputStream * @throws IOException if there was a problem */ @Override InputStream decorate(final InputStream wrapped) throws IOException { return new DeflateInputStream(wrapped); } /** * {@inheritDoc} */ @Override public Header getContentEncoding() { /* This HttpEntityWrapper has dealt with the Content-Encoding. */ return null; } /** * {@inheritDoc} */ @Override public long getContentLength() { /* Length of inflated content is unknown. */ return -1; } } ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/DeflateInputStream.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/DeflateInputStrea0100644 0000000 0000000 00000015122 12301751674 032521 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.entity; import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; import java.util.zip.DataFormatException; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; /** Deflate input stream. This class includes logic needed for various Rfc's in order * to reasonably implement the "deflate" compression style. */ public class DeflateInputStream extends InputStream { private InputStream sourceStream; public DeflateInputStream(final InputStream wrapped) throws IOException { /* * A zlib stream will have a header. * * CMF | FLG [| DICTID ] | ...compressed data | ADLER32 | * * * CMF is one byte. * * * FLG is one byte. * * * DICTID is four bytes, and only present if FLG.FDICT is set. * * Sniff the content. Does it look like a zlib stream, with a CMF, etc? c.f. RFC1950, * section 2.2. http://tools.ietf.org/html/rfc1950#page-4 * * We need to see if it looks like a proper zlib stream, or whether it is just a deflate * stream. RFC2616 calls zlib streams deflate. Confusing, isn't it? That's why some servers * implement deflate Content-Encoding using deflate streams, rather than zlib streams. * * We could start looking at the bytes, but to be honest, someone else has already read * the RFCs and implemented that for us. So we'll just use the JDK libraries and exception * handling to do this. If that proves slow, then we could potentially change this to check * the first byte - does it look like a CMF? What about the second byte - does it look like * a FLG, etc. */ /* We read a small buffer to sniff the content. */ final byte[] peeked = new byte[6]; final PushbackInputStream pushback = new PushbackInputStream(wrapped, peeked.length); final int headerLength = pushback.read(peeked); if (headerLength == -1) { throw new IOException("Unable to read the response"); } /* We try to read the first uncompressed byte. */ final byte[] dummy = new byte[1]; final Inflater inf = new Inflater(); try { int n; while ((n = inf.inflate(dummy)) == 0) { if (inf.finished()) { /* Not expecting this, so fail loudly. */ throw new IOException("Unable to read the response"); } if (inf.needsDictionary()) { /* Need dictionary - then it must be zlib stream with DICTID part? */ break; } if (inf.needsInput()) { inf.setInput(peeked); } } if (n == -1) { throw new IOException("Unable to read the response"); } /* * We read something without a problem, so it's a valid zlib stream. Just need to reset * and return an unused InputStream now. */ pushback.unread(peeked, 0, headerLength); sourceStream = new DeflateStream(pushback, new Inflater()); } catch (final DataFormatException e) { /* Presume that it's an RFC1951 deflate stream rather than RFC1950 zlib stream and try * again. */ pushback.unread(peeked, 0, headerLength); sourceStream = new DeflateStream(pushback, new Inflater(true)); } finally { inf.end(); } } /** Read a byte. */ @Override public int read() throws IOException { return sourceStream.read(); } /** Read lots of bytes. */ @Override public int read(final byte[] b) throws IOException { return sourceStream.read(b); } /** Read lots of specific bytes. */ @Override public int read(final byte[] b, final int off, final int len) throws IOException { return sourceStream.read(b,off,len); } /** Skip */ @Override public long skip(final long n) throws IOException { return sourceStream.skip(n); } /** Get available. */ @Override public int available() throws IOException { return sourceStream.available(); } /** Mark. */ @Override public void mark(final int readLimit) { sourceStream.mark(readLimit); } /** Reset. */ @Override public void reset() throws IOException { sourceStream.reset(); } /** Check if mark is supported. */ @Override public boolean markSupported() { return sourceStream.markSupported(); } /** Close. */ @Override public void close() throws IOException { sourceStream.close(); } static class DeflateStream extends InflaterInputStream { private boolean closed = false; public DeflateStream(final InputStream in, final Inflater inflater) { super(in, inflater); } @Override public void close() throws IOException { if (closed) { return; } closed = true; inf.end(); super.close(); } } } ././@LongLink0100644 0000000 0000000 00000000146 12302131604 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/EntityBuilder.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/EntityBuilder.jav0100644 0000000 0000000 00000025462 12301751674 032510 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.entity; import java.io.File; import java.io.InputStream; import java.io.Serializable; import java.util.Arrays; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.entity.AbstractHttpEntity; import org.apache.http.entity.BasicHttpEntity; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.ContentType; import org.apache.http.entity.FileEntity; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.SerializableEntity; import org.apache.http.entity.StringEntity; /** * Builder for {@link HttpEntity} instances. *

* Several setter methods of this builder are mutually exclusive. In case of multiple invocations * of the following methods only the last one will have effect: *

    *
  • {@link #setText(String)}
  • *
  • {@link #setBinary(byte[])}
  • *
  • {@link #setStream(java.io.InputStream)}
  • *
  • {@link #setSerializable(java.io.Serializable)}
  • *
  • {@link #setParameters(java.util.List)}
  • *
  • {@link #setParameters(org.apache.http.NameValuePair...)}
  • *
  • {@link #setFile(java.io.File)}
  • *
* * @since 4.3 */ @NotThreadSafe public class EntityBuilder { private String text; private byte[] binary; private InputStream stream; private List parameters; private Serializable serializable; private File file; private ContentType contentType; private String contentEncoding; private boolean chunked; private boolean gzipCompress; EntityBuilder() { super(); } public static EntityBuilder create() { return new EntityBuilder(); } private void clearContent() { this.text = null; this.binary = null; this.stream = null; this.parameters = null; this.serializable = null; this.file = null; } /** * Returns entity content as a string if set using {@link #setText(String)} method. */ public String getText() { return text; } /** * Sets entity content as a string. This method is mutually exclusive with * {@link #setBinary(byte[])}, * {@link #setStream(java.io.InputStream)} , * {@link #setSerializable(java.io.Serializable)} , * {@link #setParameters(java.util.List)}, * {@link #setParameters(org.apache.http.NameValuePair...)} * {@link #setFile(java.io.File)} methods. */ public EntityBuilder setText(final String text) { clearContent(); this.text = text; return this; } /** * Returns entity content as a byte array if set using * {@link #setBinary(byte[])} method. */ public byte[] getBinary() { return binary; } /** * Sets entity content as a byte array. This method is mutually exclusive with * {@link #setText(String)}, * {@link #setStream(java.io.InputStream)} , * {@link #setSerializable(java.io.Serializable)} , * {@link #setParameters(java.util.List)}, * {@link #setParameters(org.apache.http.NameValuePair...)} * {@link #setFile(java.io.File)} methods. */ public EntityBuilder setBinary(final byte[] binary) { clearContent(); this.binary = binary; return this; } /** * Returns entity content as a {@link InputStream} if set using * {@link #setStream(java.io.InputStream)} method. */ public InputStream getStream() { return stream; } /** * Sets entity content as a {@link InputStream}. This method is mutually exclusive with * {@link #setText(String)}, * {@link #setBinary(byte[])}, * {@link #setSerializable(java.io.Serializable)} , * {@link #setParameters(java.util.List)}, * {@link #setParameters(org.apache.http.NameValuePair...)} * {@link #setFile(java.io.File)} methods. */ public EntityBuilder setStream(final InputStream stream) { clearContent(); this.stream = stream; return this; } /** * Returns entity content as a parameter list if set using * {@link #setParameters(java.util.List)} or * {@link #setParameters(org.apache.http.NameValuePair...)} methods. */ public List getParameters() { return parameters; } /** * Sets entity content as a parameter list. This method is mutually exclusive with * {@link #setText(String)}, * {@link #setBinary(byte[])}, * {@link #setStream(java.io.InputStream)} , * {@link #setSerializable(java.io.Serializable)} , * {@link #setFile(java.io.File)} methods. */ public EntityBuilder setParameters(final List parameters) { clearContent(); this.parameters = parameters; return this; } /** * Sets entity content as a parameter list. This method is mutually exclusive with * {@link #setText(String)}, * {@link #setBinary(byte[])}, * {@link #setStream(java.io.InputStream)} , * {@link #setSerializable(java.io.Serializable)} , * {@link #setFile(java.io.File)} methods. */ public EntityBuilder setParameters(final NameValuePair... parameters) { return setParameters(Arrays.asList(parameters)); } /** * Returns entity content as a {@link Serializable} if set using * {@link #setSerializable(java.io.Serializable)} method. */ public Serializable getSerializable() { return serializable; } /** * Sets entity content as a {@link Serializable}. This method is mutually exclusive with * {@link #setText(String)}, * {@link #setBinary(byte[])}, * {@link #setStream(java.io.InputStream)} , * {@link #setParameters(java.util.List)}, * {@link #setParameters(org.apache.http.NameValuePair...)} * {@link #setFile(java.io.File)} methods. */ public EntityBuilder setSerializable(final Serializable serializable) { clearContent(); this.serializable = serializable; return this; } /** * Returns entity content as a {@link File} if set using * {@link #setFile(java.io.File)} method. */ public File getFile() { return file; } /** * Sets entity content as a {@link File}. This method is mutually exclusive with * {@link #setText(String)}, * {@link #setBinary(byte[])}, * {@link #setStream(java.io.InputStream)} , * {@link #setParameters(java.util.List)}, * {@link #setParameters(org.apache.http.NameValuePair...)} * {@link #setSerializable(java.io.Serializable)} methods. */ public EntityBuilder setFile(final File file) { clearContent(); this.file = file; return this; } /** * Returns {@link ContentType} of the entity, if set. */ public ContentType getContentType() { return contentType; } /** * Sets {@link ContentType} of the entity. */ public EntityBuilder setContentType(final ContentType contentType) { this.contentType = contentType; return this; } /** * Returns content encoding of the entity, if set. */ public String getContentEncoding() { return contentEncoding; } /** * Sets content encoding of the entity. */ public EntityBuilder setContentEncoding(final String contentEncoding) { this.contentEncoding = contentEncoding; return this; } /** * Returns true if entity is to be chunk coded, false otherwise. */ public boolean isChunked() { return chunked; } /** * Makes entity chunk coded. */ public EntityBuilder chunked() { this.chunked = true; return this; } /** * Returns true if entity is to be GZIP compressed, false otherwise. */ public boolean isGzipCompress() { return gzipCompress; } /** * Makes entity GZIP compressed. */ public EntityBuilder gzipCompress() { this.gzipCompress = true; return this; } private ContentType getContentOrDefault(final ContentType def) { return this.contentType != null ? this.contentType : def; } /** * Creates new instance of {@link HttpEntity} based on the current state. */ public HttpEntity build() { final AbstractHttpEntity e; if (this.text != null) { e = new StringEntity(this.text, getContentOrDefault(ContentType.DEFAULT_TEXT)); } else if (this.binary != null) { e = new ByteArrayEntity(this.binary, getContentOrDefault(ContentType.DEFAULT_BINARY)); } else if (this.stream != null) { e = new InputStreamEntity(this.stream, 1, getContentOrDefault(ContentType.DEFAULT_BINARY)); } else if (this.parameters != null) { e = new UrlEncodedFormEntity(this.parameters, this.contentType != null ? this.contentType.getCharset() : null); } else if (this.serializable != null) { e = new SerializableEntity(this.serializable); e.setContentType(ContentType.DEFAULT_BINARY.toString()); } else if (this.file != null) { e = new FileEntity(this.file, getContentOrDefault(ContentType.DEFAULT_BINARY)); } else { e = new BasicHttpEntity(); } if (e.getContentType() != null && this.contentType != null) { e.setContentType(this.contentType.toString()); } e.setContentEncoding(this.contentEncoding); e.setChunked(this.chunked); if (this.gzipCompress) { return new GzipCompressingEntity(e); } return e; } } ././@LongLink0100644 0000000 0000000 00000000156 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/GzipCompressingEntity.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/GzipCompressingEn0100644 0000000 0000000 00000007412 12301751674 032547 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.entity; /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.zip.GZIPOutputStream; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.entity.HttpEntityWrapper; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.HTTP; import org.apache.http.util.Args; /** * Wrapping entity that compresses content when {@link #writeTo writing}. * * * @since 4.0 */ public class GzipCompressingEntity extends HttpEntityWrapper { private static final String GZIP_CODEC = "gzip"; public GzipCompressingEntity(final HttpEntity entity) { super(entity); } @Override public Header getContentEncoding() { return new BasicHeader(HTTP.CONTENT_ENCODING, GZIP_CODEC); } @Override public long getContentLength() { return -1; } @Override public boolean isChunked() { // force content chunking return true; } @Override public InputStream getContent() throws IOException { throw new UnsupportedOperationException(); } @Override public void writeTo(final OutputStream outstream) throws IOException { Args.notNull(outstream, "Output stream"); final GZIPOutputStream gzip = new GZIPOutputStream(outstream); try { wrappedEntity.writeTo(gzip); } finally { gzip.close(); } } } ././@LongLink0100644 0000000 0000000 00000000160 12302131604 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/GzipDecompressingEntity.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/GzipDecompressing0100644 0000000 0000000 00000004531 12301751674 032574 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.entity; import java.io.IOException; import java.io.InputStream; import java.util.zip.GZIPInputStream; import org.apache.http.Header; import org.apache.http.HttpEntity; /** * {@link org.apache.http.entity.HttpEntityWrapper} for handling gzip * Content Coded responses. * * @since 4.1 */ public class GzipDecompressingEntity extends DecompressingEntity { /** * Creates a new {@link GzipDecompressingEntity} which will wrap the specified * {@link HttpEntity}. * * @param entity * the non-null {@link HttpEntity} to be wrapped */ public GzipDecompressingEntity(final HttpEntity entity) { super(entity); } @Override InputStream decorate(final InputStream wrapped) throws IOException { return new GZIPInputStream(wrapped); } /** * {@inheritDoc} */ @Override public Header getContentEncoding() { /* This HttpEntityWrapper has dealt with the Content-Encoding. */ return null; } /** * {@inheritDoc} */ @Override public long getContentLength() { /* length of ungzipped content is not known */ return -1; } } ././@LongLink0100644 0000000 0000000 00000000165 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/LazyDecompressingInputStream.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/LazyDecompressing0100644 0000000 0000000 00000005764 12301751674 032613 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.entity; import org.apache.http.annotation.NotThreadSafe; import java.io.IOException; import java.io.InputStream; /** * Lazy init InputStream wrapper. */ @NotThreadSafe class LazyDecompressingInputStream extends InputStream { private final InputStream wrappedStream; private final DecompressingEntity decompressingEntity; private InputStream wrapperStream; public LazyDecompressingInputStream( final InputStream wrappedStream, final DecompressingEntity decompressingEntity) { this.wrappedStream = wrappedStream; this.decompressingEntity = decompressingEntity; } private void initWrapper() throws IOException { if (wrapperStream == null) { wrapperStream = decompressingEntity.decorate(wrappedStream); } } @Override public int read() throws IOException { initWrapper(); return wrapperStream.read(); } @Override public int read(final byte[] b) throws IOException { initWrapper(); return wrapperStream.read(b); } @Override public int read(final byte[] b, final int off, final int len) throws IOException { initWrapper(); return wrapperStream.read(b, off, len); } @Override public long skip(final long n) throws IOException { initWrapper(); return wrapperStream.skip(n); } @Override public boolean markSupported() { return false; } @Override public int available() throws IOException { initWrapper(); return wrapperStream.available(); } @Override public void close() throws IOException { try { if (wrapperStream != null) { wrapperStream.close(); } } finally { wrappedStream.close(); } } } ././@LongLink0100644 0000000 0000000 00000000145 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/package-info.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/package-info.java0100644 0000000 0000000 00000002400 12301751674 032375 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Client specific HTTP entity implementations. */ package org.apache.http.client.entity; ././@LongLink0100644 0000000 0000000 00000000155 12302131604 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/UrlEncodedFormEntity.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/entity/UrlEncodedFormEnt0100644 0000000 0000000 00000007747 12301751674 032473 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.entity; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.protocol.HTTP; /** * An entity composed of a list of url-encoded pairs. * This is typically useful while sending an HTTP POST request. * * @since 4.0 */ @NotThreadSafe // AbstractHttpEntity is not thread-safe public class UrlEncodedFormEntity extends StringEntity { /** * Constructs a new {@link UrlEncodedFormEntity} with the list * of parameters in the specified encoding. * * @param parameters list of name/value pairs * @param charset encoding the name/value pairs be encoded with * @throws UnsupportedEncodingException if the encoding isn't supported */ public UrlEncodedFormEntity ( final List parameters, final String charset) throws UnsupportedEncodingException { super(URLEncodedUtils.format(parameters, charset != null ? charset : HTTP.DEF_CONTENT_CHARSET.name()), ContentType.create(URLEncodedUtils.CONTENT_TYPE, charset)); } /** * Constructs a new {@link UrlEncodedFormEntity} with the list * of parameters in the specified encoding. * * @param parameters iterable collection of name/value pairs * @param charset encoding the name/value pairs be encoded with * * @since 4.2 */ public UrlEncodedFormEntity ( final Iterable parameters, final Charset charset) { super(URLEncodedUtils.format(parameters, charset != null ? charset : HTTP.DEF_CONTENT_CHARSET), ContentType.create(URLEncodedUtils.CONTENT_TYPE, charset)); } /** * Constructs a new {@link UrlEncodedFormEntity} with the list * of parameters with the default encoding of {@link HTTP#DEFAULT_CONTENT_CHARSET} * * @param parameters list of name/value pairs * @throws UnsupportedEncodingException if the default encoding isn't supported */ public UrlEncodedFormEntity ( final List parameters) throws UnsupportedEncodingException { this(parameters, (Charset) null); } /** * Constructs a new {@link UrlEncodedFormEntity} with the list * of parameters with the default encoding of {@link HTTP#DEFAULT_CONTENT_CHARSET} * * @param parameters iterable collection of name/value pairs * * @since 4.2 */ public UrlEncodedFormEntity ( final Iterable parameters) { this(parameters, null); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/0040755 0000000 0000000 00000000000 12301751676 027346 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000156 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/AbortableHttpRequest.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/AbortableHttpReq0100644 0000000 0000000 00000006164 12301751676 032500 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import org.apache.http.conn.ClientConnectionRequest; import org.apache.http.conn.ConnectionReleaseTrigger; import java.io.IOException; /** * Interface representing an HTTP request that can be aborted by shutting * down the underlying HTTP connection. * * @since 4.0 * * @deprecated (4.3) use {@link HttpExecutionAware} */ @Deprecated public interface AbortableHttpRequest { /** * Sets the {@link org.apache.http.conn.ClientConnectionRequest} * callback that can be used to abort a long-lived request for a connection. * If the request is already aborted, throws an {@link IOException}. * * @see org.apache.http.conn.ClientConnectionManager */ void setConnectionRequest(ClientConnectionRequest connRequest) throws IOException; /** * Sets the {@link ConnectionReleaseTrigger} callback that can * be used to abort an active connection. * Typically, this will be the * {@link org.apache.http.conn.ManagedClientConnection} itself. * If the request is already aborted, throws an {@link IOException}. */ void setReleaseTrigger(ConnectionReleaseTrigger releaseTrigger) throws IOException; /** * Aborts this http request. Any active execution of this method should * return immediately. If the request has not started, it will abort after * the next execution. Aborting this request will cause all subsequent * executions with this request to fail. * * @see org.apache.http.client.HttpClient#execute(HttpUriRequest) * @see org.apache.http.client.HttpClient#execute(org.apache.http.HttpHost, * org.apache.http.HttpRequest) * @see org.apache.http.client.HttpClient#execute(HttpUriRequest, * org.apache.http.protocol.HttpContext) * @see org.apache.http.client.HttpClient#execute(org.apache.http.HttpHost, * org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) */ void abort(); } ././@LongLink0100644 0000000 0000000 00000000167 12302131604 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/AbstractExecutionAwareRequest.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/AbstractExecutio0100644 0000000 0000000 00000011603 12301751676 032540 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.io.IOException; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.apache.http.HttpRequest; import org.apache.http.client.utils.CloneUtils; import org.apache.http.concurrent.Cancellable; import org.apache.http.conn.ClientConnectionRequest; import org.apache.http.conn.ConnectionReleaseTrigger; import org.apache.http.message.AbstractHttpMessage; @SuppressWarnings("deprecation") public abstract class AbstractExecutionAwareRequest extends AbstractHttpMessage implements HttpExecutionAware, AbortableHttpRequest, Cloneable, HttpRequest { private Lock abortLock; private volatile boolean aborted; private volatile Cancellable cancellable; protected AbstractExecutionAwareRequest() { super(); this.abortLock = new ReentrantLock(); } @Deprecated public void setConnectionRequest(final ClientConnectionRequest connRequest) { if (this.aborted) { return; } this.abortLock.lock(); try { this.cancellable = new Cancellable() { public boolean cancel() { connRequest.abortRequest(); return true; } }; } finally { this.abortLock.unlock(); } } @Deprecated public void setReleaseTrigger(final ConnectionReleaseTrigger releaseTrigger) { if (this.aborted) { return; } this.abortLock.lock(); try { this.cancellable = new Cancellable() { public boolean cancel() { try { releaseTrigger.abortConnection(); return true; } catch (final IOException ex) { return false; } } }; } finally { this.abortLock.unlock(); } } private void cancelExecution() { if (this.cancellable != null) { this.cancellable.cancel(); this.cancellable = null; } } public void abort() { if (this.aborted) { return; } this.abortLock.lock(); try { this.aborted = true; cancelExecution(); } finally { this.abortLock.unlock(); } } public boolean isAborted() { return this.aborted; } /** * @since 4.2 */ public void setCancellable(final Cancellable cancellable) { if (this.aborted) { return; } this.abortLock.lock(); try { this.cancellable = cancellable; } finally { this.abortLock.unlock(); } } @Override public Object clone() throws CloneNotSupportedException { final AbstractExecutionAwareRequest clone = (AbstractExecutionAwareRequest) super.clone(); clone.headergroup = CloneUtils.cloneObject(this.headergroup); clone.params = CloneUtils.cloneObject(this.params); clone.abortLock = new ReentrantLock(); clone.cancellable = null; clone.aborted = false; return clone; } /** * @since 4.2 */ public void completed() { this.abortLock.lock(); try { this.cancellable = null; } finally { this.abortLock.unlock(); } } /** * Resets internal state of the request making it reusable. * * @since 4.2 */ public void reset() { this.abortLock.lock(); try { cancelExecution(); this.aborted = false; } finally { this.abortLock.unlock(); } } } ././@LongLink0100644 0000000 0000000 00000000157 12302131604 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/CloseableHttpResponse.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/CloseableHttpRes0100644 0000000 0000000 00000002716 12301751676 032477 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.io.Closeable; import org.apache.http.HttpResponse; /** * Extended version of the {@link HttpResponse} interface that also extends {@link Closeable}. * * @since 4.3 */ public interface CloseableHttpResponse extends HttpResponse, Closeable { } ././@LongLink0100644 0000000 0000000 00000000146 12302131604 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/Configurable.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/Configurable.jav0100644 0000000 0000000 00000002706 12301751676 032452 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import org.apache.http.client.config.RequestConfig; /** * Configuration interface for HTTP requests. * * @since 4.3 */ public interface Configurable { /** * Returns actual request configuration. */ RequestConfig getConfig(); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpDelete.java0100644 0000000 0000000 00000004477 12301751676 032264 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.net.URI; import org.apache.http.annotation.NotThreadSafe; /** * HTTP DELETE method *

* The HTTP DELETE method is defined in section 9.7 of * RFC2616: *

* The DELETE method requests that the origin server delete the resource * identified by the Request-URI. [...] The client cannot * be guaranteed that the operation has been carried out, even if the * status code returned from the origin server indicates that the action * has been completed successfully. *
* * @since 4.0 */ @NotThreadSafe // HttpRequestBase is @NotThreadSafe public class HttpDelete extends HttpRequestBase { public final static String METHOD_NAME = "DELETE"; public HttpDelete() { super(); } public HttpDelete(final URI uri) { super(); setURI(uri); } /** * @throws IllegalArgumentException if the uri is invalid. */ public HttpDelete(final String uri) { super(); setURI(URI.create(uri)); } @Override public String getMethod() { return METHOD_NAME; } } ././@LongLink0100644 0000000 0000000 00000000170 12302131604 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpEntityEnclosingRequestBase.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpEntityEnclos0100644 0000000 0000000 00000004777 12301751676 032565 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.client.utils.CloneUtils; import org.apache.http.protocol.HTTP; /** * Basic implementation of an entity enclosing HTTP request * that can be modified * * @since 4.0 */ @NotThreadSafe // HttpRequestBase is @NotThreadSafe public abstract class HttpEntityEnclosingRequestBase extends HttpRequestBase implements HttpEntityEnclosingRequest { private HttpEntity entity; public HttpEntityEnclosingRequestBase() { super(); } public HttpEntity getEntity() { return this.entity; } public void setEntity(final HttpEntity entity) { this.entity = entity; } public boolean expectContinue() { final Header expect = getFirstHeader(HTTP.EXPECT_DIRECTIVE); return expect != null && HTTP.EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue()); } @Override public Object clone() throws CloneNotSupportedException { final HttpEntityEnclosingRequestBase clone = (HttpEntityEnclosingRequestBase) super.clone(); if (this.entity != null) { clone.entity = CloneUtils.cloneObject(this.entity); } return clone; } } ././@LongLink0100644 0000000 0000000 00000000154 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpExecutionAware.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpExecutionAwa0100644 0000000 0000000 00000003124 12301751676 032522 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import org.apache.http.concurrent.Cancellable; /** * Interface to be implemented by any object that wishes to be notified of * blocking I/O operations that could be cancelled. * * @since 4.3 */ public interface HttpExecutionAware { boolean isAborted(); /** * Sets {@link Cancellable} for the ongoing operation. */ void setCancellable(Cancellable cancellable); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpGet.java0100644 0000000 0000000 00000004475 12301751676 031577 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.net.URI; import org.apache.http.annotation.NotThreadSafe; /** * HTTP GET method. *

* The HTTP GET method is defined in section 9.3 of * RFC2616: *

* The GET method means retrieve whatever information (in the form of an * entity) is identified by the Request-URI. If the Request-URI refers * to a data-producing process, it is the produced data which shall be * returned as the entity in the response and not the source text of the * process, unless that text happens to be the output of the process. *
*

* * @since 4.0 */ @NotThreadSafe public class HttpGet extends HttpRequestBase { public final static String METHOD_NAME = "GET"; public HttpGet() { super(); } public HttpGet(final URI uri) { super(); setURI(uri); } /** * @throws IllegalArgumentException if the uri is invalid. */ public HttpGet(final String uri) { super(); setURI(URI.create(uri)); } @Override public String getMethod() { return METHOD_NAME; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpHead.java0100644 0000000 0000000 00000004762 12301751676 031720 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.net.URI; import org.apache.http.annotation.NotThreadSafe; /** * HTTP HEAD method. *

* The HTTP HEAD method is defined in section 9.4 of * RFC2616: *

* The HEAD method is identical to GET except that the server MUST NOT * return a message-body in the response. The metainformation contained * in the HTTP headers in response to a HEAD request SHOULD be identical * to the information sent in response to a GET request. This method can * be used for obtaining metainformation about the entity implied by the * request without transferring the entity-body itself. This method is * often used for testing hypertext links for validity, accessibility, * and recent modification. *
*

* * @since 4.0 */ @NotThreadSafe public class HttpHead extends HttpRequestBase { public final static String METHOD_NAME = "HEAD"; public HttpHead() { super(); } public HttpHead(final URI uri) { super(); setURI(uri); } /** * @throws IllegalArgumentException if the uri is invalid. */ public HttpHead(final String uri) { super(); setURI(URI.create(uri)); } @Override public String getMethod() { return METHOD_NAME; } } ././@LongLink0100644 0000000 0000000 00000000145 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpOptions.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpOptions.java0100644 0000000 0000000 00000006214 12301751676 032504 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.net.URI; import java.util.HashSet; import java.util.Set; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HeaderIterator; import org.apache.http.HttpResponse; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.util.Args; /** * HTTP OPTIONS method. *

* The HTTP OPTIONS method is defined in section 9.2 of * RFC2616: *

* The OPTIONS method represents a request for information about the * communication options available on the request/response chain * identified by the Request-URI. This method allows the client to * determine the options and/or requirements associated with a resource, * or the capabilities of a server, without implying a resource action * or initiating a resource retrieval. *
*

* * @since 4.0 */ @NotThreadSafe public class HttpOptions extends HttpRequestBase { public final static String METHOD_NAME = "OPTIONS"; public HttpOptions() { super(); } public HttpOptions(final URI uri) { super(); setURI(uri); } /** * @throws IllegalArgumentException if the uri is invalid. */ public HttpOptions(final String uri) { super(); setURI(URI.create(uri)); } @Override public String getMethod() { return METHOD_NAME; } public Set getAllowedMethods(final HttpResponse response) { Args.notNull(response, "HTTP response"); final HeaderIterator it = response.headerIterator("Allow"); final Set methods = new HashSet(); while (it.hasNext()) { final Header header = it.nextHeader(); final HeaderElement[] elements = header.getElements(); for (final HeaderElement element : elements) { methods.add(element.getName()); } } return methods; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpPatch.java0100644 0000000 0000000 00000004745 12301751676 032117 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.net.URI; import org.apache.http.annotation.NotThreadSafe; /** * HTTP PATCH method. *

* The HTTP PATCH method is defined in RF5789:

The PATCH * method requests that a set of changes described in the request entity be * applied to the resource identified by the Request- URI. Differs from the PUT * method in the way the server processes the enclosed entity to modify the * resource identified by the Request-URI. In a PUT request, the enclosed entity * origin server, and the client is requesting that the stored version be * replaced. With PATCH, however, the enclosed entity contains a set of * instructions describing how a resource currently residing on the origin * server should be modified to produce a new version.
*

* * @since 4.2 */ @NotThreadSafe public class HttpPatch extends HttpEntityEnclosingRequestBase { public final static String METHOD_NAME = "PATCH"; public HttpPatch() { super(); } public HttpPatch(final URI uri) { super(); setURI(uri); } public HttpPatch(final String uri) { super(); setURI(URI.create(uri)); } @Override public String getMethod() { return METHOD_NAME; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpPost.java0100644 0000000 0000000 00000005147 12301751676 032002 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.net.URI; import org.apache.http.annotation.NotThreadSafe; /** * HTTP POST method. *

* The HTTP POST method is defined in section 9.5 of * RFC2616: *

* The POST method is used to request that the origin server accept the entity * enclosed in the request as a new subordinate of the resource identified by * the Request-URI in the Request-Line. POST is designed to allow a uniform * method to cover the following functions: *
    *
  • Annotation of existing resources
  • *
  • Posting a message to a bulletin board, newsgroup, mailing list, or * similar group of articles
  • *
  • Providing a block of data, such as the result of submitting a form, * to a data-handling process
  • *
  • Extending a database through an append operation
  • *
*
*

* * @since 4.0 */ @NotThreadSafe public class HttpPost extends HttpEntityEnclosingRequestBase { public final static String METHOD_NAME = "POST"; public HttpPost() { super(); } public HttpPost(final URI uri) { super(); setURI(uri); } /** * @throws IllegalArgumentException if the uri is invalid. */ public HttpPost(final String uri) { super(); setURI(URI.create(uri)); } @Override public String getMethod() { return METHOD_NAME; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpPut.java0100644 0000000 0000000 00000004361 12301751676 031622 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.net.URI; import org.apache.http.annotation.NotThreadSafe; /** * HTTP PUT method. *

* The HTTP PUT method is defined in section 9.6 of * RFC2616: *

* The PUT method requests that the enclosed entity be stored under the * supplied Request-URI. If the Request-URI refers to an already * existing resource, the enclosed entity SHOULD be considered as a * modified version of the one residing on the origin server. *
*

* * @since 4.0 */ @NotThreadSafe public class HttpPut extends HttpEntityEnclosingRequestBase { public final static String METHOD_NAME = "PUT"; public HttpPut() { super(); } public HttpPut(final URI uri) { super(); setURI(uri); } /** * @throws IllegalArgumentException if the uri is invalid. */ public HttpPut(final String uri) { super(); setURI(URI.create(uri)); } @Override public String getMethod() { return METHOD_NAME; } } ././@LongLink0100644 0000000 0000000 00000000151 12302131604 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpRequestBase.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpRequestBase.0100644 0000000 0000000 00000006772 12301751676 032443 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.net.URI; import org.apache.http.ProtocolVersion; import org.apache.http.RequestLine; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.client.config.RequestConfig; import org.apache.http.message.BasicRequestLine; import org.apache.http.params.HttpProtocolParams; /** * Base implementation of {@link HttpUriRequest}. * * @since 4.0 */ @SuppressWarnings("deprecation") @NotThreadSafe public abstract class HttpRequestBase extends AbstractExecutionAwareRequest implements HttpUriRequest, Configurable { private ProtocolVersion version; private URI uri; private RequestConfig config; public abstract String getMethod(); /** * @since 4.3 */ public void setProtocolVersion(final ProtocolVersion version) { this.version = version; } public ProtocolVersion getProtocolVersion() { return version != null ? version : HttpProtocolParams.getVersion(getParams()); } /** * Returns the original request URI. *

* Please note URI remains unchanged in the course of request execution and * is not updated if the request is redirected to another location. */ public URI getURI() { return this.uri; } public RequestLine getRequestLine() { final String method = getMethod(); final ProtocolVersion ver = getProtocolVersion(); final URI uri = getURI(); String uritext = null; if (uri != null) { uritext = uri.toASCIIString(); } if (uritext == null || uritext.length() == 0) { uritext = "/"; } return new BasicRequestLine(method, uritext, ver); } public RequestConfig getConfig() { return config; } public void setConfig(final RequestConfig config) { this.config = config; } public void setURI(final URI uri) { this.uri = uri; } /** * @since 4.2 */ public void started() { } /** * A convenience method to simplify migration from HttpClient 3.1 API. This method is * equivalent to {@link #reset()}. * * @since 4.2 */ public void releaseConnection() { reset(); } @Override public String toString() { return getMethod() + " " + getURI() + " " + getProtocolVersion(); } } ././@LongLink0100644 0000000 0000000 00000000154 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpRequestWrapper.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpRequestWrapp0100644 0000000 0000000 00000012310 12301751676 032565 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.net.URI; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.ProtocolVersion; import org.apache.http.RequestLine; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.message.AbstractHttpMessage; import org.apache.http.message.BasicRequestLine; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HTTP; /** * A wrapper class for {@link HttpRequest} that can be used to change properties of the current * request without modifying the original object. * * @since 4.3 */ @SuppressWarnings("deprecation") @NotThreadSafe public class HttpRequestWrapper extends AbstractHttpMessage implements HttpUriRequest { private final HttpRequest original; private final String method; private ProtocolVersion version; private URI uri; private HttpRequestWrapper(final HttpRequest request) { super(); this.original = request; this.version = this.original.getRequestLine().getProtocolVersion(); this.method = this.original.getRequestLine().getMethod(); if (request instanceof HttpUriRequest) { this.uri = ((HttpUriRequest) request).getURI(); } else { this.uri = null; } setHeaders(request.getAllHeaders()); } public ProtocolVersion getProtocolVersion() { return this.version != null ? this.version : this.original.getProtocolVersion(); } public void setProtocolVersion(final ProtocolVersion version) { this.version = version; } public URI getURI() { return this.uri; } public void setURI(final URI uri) { this.uri = uri; } public String getMethod() { return method; } public void abort() throws UnsupportedOperationException { throw new UnsupportedOperationException(); } public boolean isAborted() { return false; } public RequestLine getRequestLine() { String requestUri = null; if (this.uri != null) { requestUri = this.uri.toASCIIString(); } else { requestUri = this.original.getRequestLine().getUri(); } if (requestUri == null || requestUri.length() == 0) { requestUri = "/"; } return new BasicRequestLine(this.method, requestUri, getProtocolVersion()); } public HttpRequest getOriginal() { return this.original; } @Override public String toString() { return getRequestLine() + " " + this.headergroup; } static class HttpEntityEnclosingRequestWrapper extends HttpRequestWrapper implements HttpEntityEnclosingRequest { private HttpEntity entity; public HttpEntityEnclosingRequestWrapper(final HttpEntityEnclosingRequest request) { super(request); this.entity = request.getEntity(); } public HttpEntity getEntity() { return this.entity; } public void setEntity(final HttpEntity entity) { this.entity = entity; } public boolean expectContinue() { final Header expect = getFirstHeader(HTTP.EXPECT_DIRECTIVE); return expect != null && HTTP.EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue()); } } public static HttpRequestWrapper wrap(final HttpRequest request) { if (request == null) { return null; } if (request instanceof HttpEntityEnclosingRequest) { return new HttpEntityEnclosingRequestWrapper((HttpEntityEnclosingRequest) request); } else { return new HttpRequestWrapper(request); } } /** * @deprecated (4.3) use * {@link org.apache.http.client.config.RequestConfig}. */ @Override @Deprecated public HttpParams getParams() { if (this.params == null) { this.params = original.getParams().copy(); } return this.params; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpTrace.java0100644 0000000 0000000 00000004662 12301751676 032114 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.net.URI; import org.apache.http.annotation.NotThreadSafe; /** * HTTP TRACE method. *

* The HTTP TRACE method is defined in section 9.6 of * RFC2616: *

* The TRACE method is used to invoke a remote, application-layer loop- * back of the request message. The final recipient of the request * SHOULD reflect the message received back to the client as the * entity-body of a 200 (OK) response. The final recipient is either the * origin server or the first proxy or gateway to receive a Max-Forwards * value of zero (0) in the request (see section 14.31). A TRACE request * MUST NOT include an entity. *
*

* * @since 4.0 */ @NotThreadSafe public class HttpTrace extends HttpRequestBase { public final static String METHOD_NAME = "TRACE"; public HttpTrace() { super(); } public HttpTrace(final URI uri) { super(); setURI(uri); } /** * @throws IllegalArgumentException if the uri is invalid. */ public HttpTrace(final String uri) { super(); setURI(URI.create(uri)); } @Override public String getMethod() { return METHOD_NAME; } } ././@LongLink0100644 0000000 0000000 00000000150 12302131604 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpUriRequest.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/HttpUriRequest.j0100644 0000000 0000000 00000005504 12301751676 032472 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.net.URI; import org.apache.http.HttpRequest; /** * Extended version of the {@link HttpRequest} interface that provides * convenience methods to access request properties such as request URI * and method type. * * @since 4.0 */ public interface HttpUriRequest extends HttpRequest { /** * Returns the HTTP method this request uses, such as GET, * PUT, POST, or other. */ String getMethod(); /** * Returns the URI this request uses, such as * http://example.org/path/to/file. *
* Note that the URI may be absolute URI (as above) or may be a relative URI. *

* Implementations are encouraged to return * the URI that was initially requested. *

*

* To find the final URI after any redirects have been processed, * please see the section entitled * HTTP execution context * in the * HttpClient Tutorial *

*/ URI getURI(); /** * Aborts execution of the request. * * @throws UnsupportedOperationException if the abort operation * is not supported / cannot be implemented. */ void abort() throws UnsupportedOperationException; /** * Tests if the request execution has been aborted. * * @return true if the request execution has been aborted, * false otherwise. */ boolean isAborted(); } ././@LongLink0100644 0000000 0000000 00000000146 12302131604 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/package-info.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/package-info.jav0100644 0000000 0000000 00000002372 12301751676 032375 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Standard HTTP method implementations. */ package org.apache.http.client.methods; ././@LongLink0100644 0000000 0000000 00000000150 12302131604 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/RequestBuilder.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/methods/RequestBuilder.j0100644 0000000 0000000 00000025112 12301751676 032456 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import org.apache.http.Header; import org.apache.http.HeaderIterator; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.NameValuePair; import org.apache.http.ProtocolVersion; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.utils.URIBuilder; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicNameValuePair; import org.apache.http.message.HeaderGroup; import org.apache.http.protocol.HTTP; import org.apache.http.util.Args; /** * Builder for {@link HttpUriRequest} instances. *

* Please note that this class treats parameters differently depending on composition * of the request: if the request has a content entity explicitly set with * {@link #setEntity(org.apache.http.HttpEntity)} or it is not an entity enclosing method * (such as POST or PUT), parameters will be added to the query component of the request URI. * Otherwise, parameters will be added as a URL encoded {@link UrlEncodedFormEntity entity}. * * @since 4.3 */ @NotThreadSafe public class RequestBuilder { private String method; private ProtocolVersion version; private URI uri; private HeaderGroup headergroup; private HttpEntity entity; private LinkedList parameters; private RequestConfig config; RequestBuilder(final String method) { super(); this.method = method; } RequestBuilder() { this(null); } public static RequestBuilder create(final String method) { Args.notBlank(method, "HTTP method"); return new RequestBuilder(method); } public static RequestBuilder get() { return new RequestBuilder(HttpGet.METHOD_NAME); } public static RequestBuilder head() { return new RequestBuilder(HttpHead.METHOD_NAME); } public static RequestBuilder post() { return new RequestBuilder(HttpPost.METHOD_NAME); } public static RequestBuilder put() { return new RequestBuilder(HttpPut.METHOD_NAME); } public static RequestBuilder delete() { return new RequestBuilder(HttpDelete.METHOD_NAME); } public static RequestBuilder trace() { return new RequestBuilder(HttpTrace.METHOD_NAME); } public static RequestBuilder options() { return new RequestBuilder(HttpOptions.METHOD_NAME); } public static RequestBuilder copy(final HttpRequest request) { Args.notNull(request, "HTTP request"); return new RequestBuilder().doCopy(request); } private RequestBuilder doCopy(final HttpRequest request) { if (request == null) { return this; } method = request.getRequestLine().getMethod(); version = request.getRequestLine().getProtocolVersion(); if (request instanceof HttpUriRequest) { uri = ((HttpUriRequest) request).getURI(); } else { uri = URI.create(request.getRequestLine().getMethod()); } if (headergroup == null) { headergroup = new HeaderGroup(); } headergroup.clear(); headergroup.setHeaders(request.getAllHeaders()); if (request instanceof HttpEntityEnclosingRequest) { entity = ((HttpEntityEnclosingRequest) request).getEntity(); } else { entity = null; } if (request instanceof Configurable) { this.config = ((Configurable) request).getConfig(); } else { this.config = null; } this.parameters = null; return this; } public String getMethod() { return method; } public ProtocolVersion getVersion() { return version; } public RequestBuilder setVersion(final ProtocolVersion version) { this.version = version; return this; } public URI getUri() { return uri; } public RequestBuilder setUri(final URI uri) { this.uri = uri; return this; } public RequestBuilder setUri(final String uri) { this.uri = uri != null ? URI.create(uri) : null; return this; } public Header getFirstHeader(final String name) { return headergroup != null ? headergroup.getFirstHeader(name) : null; } public Header getLastHeader(final String name) { return headergroup != null ? headergroup.getLastHeader(name) : null; } public Header[] getHeaders(final String name) { return headergroup != null ? headergroup.getHeaders(name) : null; } public RequestBuilder addHeader(final Header header) { if (headergroup == null) { headergroup = new HeaderGroup(); } headergroup.addHeader(header); return this; } public RequestBuilder addHeader(final String name, final String value) { if (headergroup == null) { headergroup = new HeaderGroup(); } this.headergroup.addHeader(new BasicHeader(name, value)); return this; } public RequestBuilder removeHeader(final Header header) { if (headergroup == null) { headergroup = new HeaderGroup(); } headergroup.removeHeader(header); return this; } public RequestBuilder removeHeaders(final String name) { if (name == null || headergroup == null) { return this; } for (final HeaderIterator i = headergroup.iterator(); i.hasNext(); ) { final Header header = i.nextHeader(); if (name.equalsIgnoreCase(header.getName())) { i.remove(); } } return this; } public RequestBuilder setHeader(final Header header) { if (headergroup == null) { headergroup = new HeaderGroup(); } this.headergroup.updateHeader(header); return this; } public RequestBuilder setHeader(final String name, final String value) { if (headergroup == null) { headergroup = new HeaderGroup(); } this.headergroup.updateHeader(new BasicHeader(name, value)); return this; } public HttpEntity getEntity() { return entity; } public RequestBuilder setEntity(final HttpEntity entity) { this.entity = entity; return this; } public List getParameters() { return parameters != null ? new ArrayList(parameters) : new ArrayList(); } public RequestBuilder addParameter(final NameValuePair nvp) { Args.notNull(nvp, "Name value pair"); if (parameters == null) { parameters = new LinkedList(); } parameters.add(nvp); return this; } public RequestBuilder addParameter(final String name, final String value) { return addParameter(new BasicNameValuePair(name, value)); } public RequestBuilder addParameters(final NameValuePair... nvps) { for (final NameValuePair nvp: nvps) { addParameter(nvp); } return this; } public RequestConfig getConfig() { return config; } public RequestBuilder setConfig(final RequestConfig config) { this.config = config; return this; } public HttpUriRequest build() { final HttpRequestBase result; URI uri = this.uri != null ? this.uri : URI.create("/"); HttpEntity entity = this.entity; if (parameters != null && !parameters.isEmpty()) { if (entity == null && (HttpPost.METHOD_NAME.equalsIgnoreCase(method) || HttpPut.METHOD_NAME.equalsIgnoreCase(method))) { entity = new UrlEncodedFormEntity(parameters, HTTP.DEF_CONTENT_CHARSET); } else { try { uri = new URIBuilder(uri).addParameters(parameters).build(); } catch (final URISyntaxException ex) { // should never happen } } } if (entity == null) { result = new InternalRequest(method); } else { final InternalEntityEclosingRequest request = new InternalEntityEclosingRequest(method); request.setEntity(entity); result = request; } result.setProtocolVersion(this.version); result.setURI(uri); if (this.headergroup != null) { result.setHeaders(this.headergroup.getAllHeaders()); } result.setConfig(this.config); return result; } static class InternalRequest extends HttpRequestBase { private final String method; InternalRequest(final String method) { super(); this.method = method; } @Override public String getMethod() { return this.method; } } static class InternalEntityEclosingRequest extends HttpEntityEnclosingRequestBase { private final String method; InternalEntityEclosingRequest(final String method) { super(); this.method = method; } @Override public String getMethod() { return this.method; } } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/params/0040755 0000000 0000000 00000000000 12301751674 027164 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000150 12302131604 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/params/AllClientPNames.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/params/AllClientPNames.j0100644 0000000 0000000 00000004767 12301751674 032325 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.params; import org.apache.http.auth.params.AuthPNames; import org.apache.http.conn.params.ConnConnectionPNames; import org.apache.http.conn.params.ConnManagerPNames; import org.apache.http.conn.params.ConnRoutePNames; import org.apache.http.cookie.params.CookieSpecPNames; import org.apache.http.params.CoreConnectionPNames; import org.apache.http.params.CoreProtocolPNames; /** * Collected parameter names for the HttpClient module. * This interface combines the parameter definitions of the HttpClient * module and all dependency modules or informational units. * It does not define additional parameter names, but references * other interfaces defining parameter names. *
* This interface is meant as a navigation aid for developers. * When referring to parameter names, you should use the interfaces * in which the respective constants are actually defined. * * @since 4.0 * * @deprecated (4.3) use * {@link org.apache.http.client.config.RequestConfig}, * {@link org.apache.http.config.ConnectionConfig}, * {@link org.apache.http.config.SocketConfig} */ @Deprecated public interface AllClientPNames extends CoreConnectionPNames, CoreProtocolPNames, ClientPNames, AuthPNames, CookieSpecPNames, ConnConnectionPNames, ConnManagerPNames, ConnRoutePNames { // no additional definitions } ././@LongLink0100644 0000000 0000000 00000000145 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/params/ClientPNames.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/params/ClientPNames.java0100644 0000000 0000000 00000011431 12301751674 032346 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.params; /** * Parameter names for HTTP client parameters. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.client.config.RequestConfig}. */ @Deprecated public interface ClientPNames { public static final String CONNECTION_MANAGER_FACTORY_CLASS_NAME = "http.connection-manager.factory-class-name"; /** * Defines whether redirects should be handled automatically *

* This parameter expects a value of type {@link Boolean}. *

*/ public static final String HANDLE_REDIRECTS = "http.protocol.handle-redirects"; /** * Defines whether relative redirects should be rejected. HTTP specification * requires the location value be an absolute URI. *

* This parameter expects a value of type {@link Boolean}. *

*/ public static final String REJECT_RELATIVE_REDIRECT = "http.protocol.reject-relative-redirect"; /** * Defines the maximum number of redirects to be followed. * The limit on number of redirects is intended to prevent infinite loops. *

* This parameter expects a value of type {@link Integer}. *

*/ public static final String MAX_REDIRECTS = "http.protocol.max-redirects"; /** * Defines whether circular redirects (redirects to the same location) should be allowed. * The HTTP spec is not sufficiently clear whether circular redirects are permitted, * therefore optionally they can be enabled *

* This parameter expects a value of type {@link Boolean}. *

*/ public static final String ALLOW_CIRCULAR_REDIRECTS = "http.protocol.allow-circular-redirects"; /** * Defines whether authentication should be handled automatically. *

* This parameter expects a value of type {@link Boolean}. *

*/ public static final String HANDLE_AUTHENTICATION = "http.protocol.handle-authentication"; /** * Defines the name of the cookie specification to be used for HTTP state management. *

* This parameter expects a value of type {@link String}. *

*/ public static final String COOKIE_POLICY = "http.protocol.cookie-policy"; /** * Defines the virtual host to be used in the Host * request header instead of the physical host. *

* This parameter expects a value of type {@link org.apache.http.HttpHost}. *

* If a port is not provided, it will be derived from the request URL. */ public static final String VIRTUAL_HOST = "http.virtual-host"; /** * Defines the request headers to be sent per default with each request. *

* This parameter expects a value of type {@link java.util.Collection}. The * collection is expected to contain {@link org.apache.http.Header}s. *

*/ public static final String DEFAULT_HEADERS = "http.default-headers"; /** * Defines the default host. The default value will be used if the target host is * not explicitly specified in the request URI. *

* This parameter expects a value of type {@link org.apache.http.HttpHost}. *

*/ public static final String DEFAULT_HOST = "http.default-host"; /** * Defines the timeout in milliseconds used when retrieving an instance of * {@link org.apache.http.conn.ManagedClientConnection} from the * {@link org.apache.http.conn.ClientConnectionManager}. *

* This parameter expects a value of type {@link Long}. *

* @since 4.2 */ public static final String CONN_MANAGER_TIMEOUT = "http.conn-manager.timeout"; } ././@LongLink0100644 0000000 0000000 00000000156 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/params/HttpClientParamConfig.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/params/HttpClientParamCo0100644 0000000 0000000 00000007627 12301751674 032441 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.params; import java.net.InetAddress; import java.util.Collection; import org.apache.http.HttpHost; import org.apache.http.auth.params.AuthPNames; import org.apache.http.client.config.RequestConfig; import org.apache.http.conn.params.ConnRoutePNames; import org.apache.http.params.CoreConnectionPNames; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.params.HttpParams; /** * @deprecated (4.3) provided for compatibility with {@link HttpParams}. Do not use. * * @since 4.3 */ @Deprecated public final class HttpClientParamConfig { private HttpClientParamConfig() { } @SuppressWarnings("unchecked") public static RequestConfig getRequestConfig(final HttpParams params) { return RequestConfig.custom() .setSocketTimeout(params.getIntParameter( CoreConnectionPNames.SO_TIMEOUT, 0)) .setStaleConnectionCheckEnabled(params.getBooleanParameter( CoreConnectionPNames.STALE_CONNECTION_CHECK, true)) .setConnectTimeout(params.getIntParameter( CoreConnectionPNames.CONNECTION_TIMEOUT, 0)) .setExpectContinueEnabled(params.getBooleanParameter( CoreProtocolPNames.USE_EXPECT_CONTINUE, false)) .setProxy((HttpHost) params.getParameter( ConnRoutePNames.DEFAULT_PROXY)) .setLocalAddress((InetAddress) params.getParameter( ConnRoutePNames.LOCAL_ADDRESS)) .setProxyPreferredAuthSchemes((Collection) params.getParameter( AuthPNames.PROXY_AUTH_PREF)) .setTargetPreferredAuthSchemes((Collection) params.getParameter( AuthPNames.TARGET_AUTH_PREF)) .setAuthenticationEnabled(params.getBooleanParameter( ClientPNames.HANDLE_AUTHENTICATION, true)) .setCircularRedirectsAllowed(params.getBooleanParameter( ClientPNames.ALLOW_CIRCULAR_REDIRECTS, false)) .setConnectionRequestTimeout((int) params.getLongParameter( ClientPNames.CONN_MANAGER_TIMEOUT, 0)) .setCookieSpec((String) params.getParameter( ClientPNames.COOKIE_POLICY)) .setMaxRedirects(params.getIntParameter( ClientPNames.MAX_REDIRECTS, 50)) .setRedirectsEnabled(params.getBooleanParameter( ClientPNames.HANDLE_REDIRECTS, true)) .setRelativeRedirectsAllowed(!params.getBooleanParameter( ClientPNames.REJECT_RELATIVE_REDIRECT, false)) .build(); } } ././@LongLink0100644 0000000 0000000 00000000145 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/params/package-info.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/params/package-info.java0100644 0000000 0000000 00000002365 12301751674 032356 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Deprecated. * @deprecated (4.3). */ package org.apache.http.client.params; httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/0040755 0000000 0000000 00000000000 12301751676 027544 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000154 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/HttpClientContext.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/HttpClientConte0100644 0000000 0000000 00000020647 12301751676 032544 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.net.URI; import java.util.List; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.auth.AuthState; import org.apache.http.client.AuthCache; import org.apache.http.client.CookieStore; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.RequestConfig; import org.apache.http.config.Lookup; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.RouteInfo; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.CookieSpecProvider; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpCoreContext; /** * Adaptor class that provides convenience type safe setters and getters * for common {@link HttpContext} attributes used in the course * of HTTP request execution. * * @since 4.3 */ @NotThreadSafe public class HttpClientContext extends HttpCoreContext { /** * Attribute name of a {@link org.apache.http.conn.routing.RouteInfo} * object that represents the actual connection route. */ public static final String HTTP_ROUTE = "http.route"; /** * Attribute name of a {@link List} object that represents a collection of all * redirect locations received in the process of request execution. */ public static final String REDIRECT_LOCATIONS = "http.protocol.redirect-locations"; /** * Attribute name of a {@link org.apache.http.config.Lookup} object that represents * the actual {@link CookieSpecProvider} registry. */ public static final String COOKIESPEC_REGISTRY = "http.cookiespec-registry"; /** * Attribute name of a {@link org.apache.http.cookie.CookieSpec} * object that represents the actual cookie specification. */ public static final String COOKIE_SPEC = "http.cookie-spec"; /** * Attribute name of a {@link org.apache.http.cookie.CookieOrigin} * object that represents the actual details of the origin server. */ public static final String COOKIE_ORIGIN = "http.cookie-origin"; /** * Attribute name of a {@link org.apache.http.client.CookieStore} * object that represents the actual cookie store. */ public static final String COOKIE_STORE = "http.cookie-store"; /** * Attribute name of a {@link org.apache.http.client.CredentialsProvider} * object that represents the actual credentials provider. */ public static final String CREDS_PROVIDER = "http.auth.credentials-provider"; /** * Attribute name of a {@link org.apache.http.client.AuthCache} object * that represents the auth scheme cache. */ public static final String AUTH_CACHE = "http.auth.auth-cache"; /** * Attribute name of a {@link org.apache.http.auth.AuthState} * object that represents the actual target authentication state. */ public static final String TARGET_AUTH_STATE = "http.auth.target-scope"; /** * Attribute name of a {@link org.apache.http.auth.AuthState} * object that represents the actual proxy authentication state. */ public static final String PROXY_AUTH_STATE = "http.auth.proxy-scope"; /** * Attribute name of a {@link java.lang.Object} object that represents * the actual user identity such as user {@link java.security.Principal}. */ public static final String USER_TOKEN = "http.user-token"; /** * Attribute name of a {@link org.apache.http.config.Lookup} object that represents * the actual {@link AuthSchemeProvider} registry. */ public static final String AUTHSCHEME_REGISTRY = "http.authscheme-registry"; /** * Attribute name of a {@link org.apache.http.client.config.RequestConfig} object that * represents the actual request configuration. */ public static final String REQUEST_CONFIG = "http.request-config"; public static HttpClientContext adapt(final HttpContext context) { if (context instanceof HttpClientContext) { return (HttpClientContext) context; } else { return new HttpClientContext(context); } } public static HttpClientContext create() { return new HttpClientContext(new BasicHttpContext()); } public HttpClientContext(final HttpContext context) { super(context); } public HttpClientContext() { super(); } public RouteInfo getHttpRoute() { return getAttribute(HTTP_ROUTE, HttpRoute.class); } @SuppressWarnings("unchecked") public List getRedirectLocations() { return getAttribute(REDIRECT_LOCATIONS, List.class); } public CookieStore getCookieStore() { return getAttribute(COOKIE_STORE, CookieStore.class); } public void setCookieStore(final CookieStore cookieStore) { setAttribute(COOKIE_STORE, cookieStore); } public CookieSpec getCookieSpec() { return getAttribute(COOKIE_SPEC, CookieSpec.class); } public CookieOrigin getCookieOrigin() { return getAttribute(COOKIE_ORIGIN, CookieOrigin.class); } @SuppressWarnings("unchecked") private Lookup getLookup(final String name, final Class clazz) { return getAttribute(name, Lookup.class); } public Lookup getCookieSpecRegistry() { return getLookup(COOKIESPEC_REGISTRY, CookieSpecProvider.class); } public void setCookieSpecRegistry(final Lookup lookup) { setAttribute(COOKIESPEC_REGISTRY, lookup); } public Lookup getAuthSchemeRegistry() { return getLookup(AUTHSCHEME_REGISTRY, AuthSchemeProvider.class); } public void setAuthSchemeRegistry(final Lookup lookup) { setAttribute(AUTHSCHEME_REGISTRY, lookup); } public CredentialsProvider getCredentialsProvider() { return getAttribute(CREDS_PROVIDER, CredentialsProvider.class); } public void setCredentialsProvider(final CredentialsProvider credentialsProvider) { setAttribute(CREDS_PROVIDER, credentialsProvider); } public AuthCache getAuthCache() { return getAttribute(AUTH_CACHE, AuthCache.class); } public void setAuthCache(final AuthCache authCache) { setAttribute(AUTH_CACHE, authCache); } public AuthState getTargetAuthState() { return getAttribute(TARGET_AUTH_STATE, AuthState.class); } public AuthState getProxyAuthState() { return getAttribute(PROXY_AUTH_STATE, AuthState.class); } public T getUserToken(final Class clazz) { return getAttribute(USER_TOKEN, clazz); } public Object getUserToken() { return getAttribute(USER_TOKEN); } public void setUserToken(final Object obj) { setAttribute(USER_TOKEN, obj); } public RequestConfig getRequestConfig() { final RequestConfig config = getAttribute(REQUEST_CONFIG, RequestConfig.class); return config != null ? config : RequestConfig.DEFAULT; } public void setRequestConfig(final RequestConfig config) { setAttribute(REQUEST_CONFIG, config); } } ././@LongLink0100644 0000000 0000000 00000000147 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/package-info.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/package-info.ja0100644 0000000 0000000 00000002375 12301751676 032410 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Client specific HTTP protocol handlers. */ package org.apache.http.client.protocol; ././@LongLink0100644 0000000 0000000 00000000160 12302131604 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/RequestAcceptEncoding.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/RequestAcceptEn0100644 0000000 0000000 00000004323 12301751676 032521 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.io.IOException; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.annotation.Immutable; import org.apache.http.protocol.HttpContext; /** * Class responsible for handling Content Encoding requests in HTTP. *

* Instances of this class are stateless, therefore they're thread-safe and immutable. * * @see "http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5" * * @since 4.1 */ @Immutable public class RequestAcceptEncoding implements HttpRequestInterceptor { /** * Adds the header {@code "Accept-Encoding: gzip,deflate"} to the request. */ public void process( final HttpRequest request, final HttpContext context) throws HttpException, IOException { /* Signal support for Accept-Encoding transfer encodings. */ if (!request.containsHeader("Accept-Encoding")) { request.addHeader("Accept-Encoding", "gzip,deflate"); } } } ././@LongLink0100644 0000000 0000000 00000000154 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/RequestAddCookies.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/RequestAddCooki0100644 0000000 0000000 00000017047 12301751676 032523 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.annotation.Immutable; import org.apache.http.client.CookieStore; import org.apache.http.client.config.CookieSpecs; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.config.Lookup; import org.apache.http.conn.routing.RouteInfo; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.CookieSpecProvider; import org.apache.http.cookie.SetCookie2; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.TextUtils; /** * Request interceptor that matches cookies available in the current * {@link CookieStore} to the request being executed and generates * corresponding Cookie request headers. * * @since 4.0 */ @Immutable public class RequestAddCookies implements HttpRequestInterceptor { private final Log log = LogFactory.getLog(getClass()); public RequestAddCookies() { super(); } public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { Args.notNull(request, "HTTP request"); Args.notNull(context, "HTTP context"); final String method = request.getRequestLine().getMethod(); if (method.equalsIgnoreCase("CONNECT")) { return; } final HttpClientContext clientContext = HttpClientContext.adapt(context); // Obtain cookie store final CookieStore cookieStore = clientContext.getCookieStore(); if (cookieStore == null) { this.log.debug("Cookie store not specified in HTTP context"); return; } // Obtain the registry of cookie specs final Lookup registry = clientContext.getCookieSpecRegistry(); if (registry == null) { this.log.debug("CookieSpec registry not specified in HTTP context"); return; } // Obtain the target host, possibly virtual (required) final HttpHost targetHost = clientContext.getTargetHost(); if (targetHost == null) { this.log.debug("Target host not set in the context"); return; } // Obtain the route (required) final RouteInfo route = clientContext.getHttpRoute(); if (route == null) { this.log.debug("Connection route not set in the context"); return; } final RequestConfig config = clientContext.getRequestConfig(); String policy = config.getCookieSpec(); if (policy == null) { policy = CookieSpecs.BEST_MATCH; } if (this.log.isDebugEnabled()) { this.log.debug("CookieSpec selected: " + policy); } URI requestURI = null; if (request instanceof HttpUriRequest) { requestURI = ((HttpUriRequest) request).getURI(); } else { try { requestURI = new URI(request.getRequestLine().getUri()); } catch (final URISyntaxException ignore) { } } final String path = requestURI != null ? requestURI.getPath() : null; final String hostName = targetHost.getHostName(); int port = targetHost.getPort(); if (port < 0) { port = route.getTargetHost().getPort(); } final CookieOrigin cookieOrigin = new CookieOrigin( hostName, port >= 0 ? port : 0, !TextUtils.isEmpty(path) ? path : "/", route.isSecure()); // Get an instance of the selected cookie policy final CookieSpecProvider provider = registry.lookup(policy); if (provider == null) { throw new HttpException("Unsupported cookie policy: " + policy); } final CookieSpec cookieSpec = provider.create(clientContext); // Get all cookies available in the HTTP state final List cookies = new ArrayList(cookieStore.getCookies()); // Find cookies matching the given origin final List matchedCookies = new ArrayList(); final Date now = new Date(); for (final Cookie cookie : cookies) { if (!cookie.isExpired(now)) { if (cookieSpec.match(cookie, cookieOrigin)) { if (this.log.isDebugEnabled()) { this.log.debug("Cookie " + cookie + " match " + cookieOrigin); } matchedCookies.add(cookie); } } else { if (this.log.isDebugEnabled()) { this.log.debug("Cookie " + cookie + " expired"); } } } // Generate Cookie request headers if (!matchedCookies.isEmpty()) { final List

headers = cookieSpec.formatCookies(matchedCookies); for (final Header header : headers) { request.addHeader(header); } } final int ver = cookieSpec.getVersion(); if (ver > 0) { boolean needVersionHeader = false; for (final Cookie cookie : matchedCookies) { if (ver != cookie.getVersion() || !(cookie instanceof SetCookie2)) { needVersionHeader = true; } } if (needVersionHeader) { final Header header = cookieSpec.getVersionHeader(); if (header != null) { // Advertise cookie version support request.addHeader(header); } } } // Stick the CookieSpec and CookieOrigin instances to the HTTP context // so they could be obtained by the response interceptor context.setAttribute(HttpClientContext.COOKIE_SPEC, cookieSpec); context.setAttribute(HttpClientContext.COOKIE_ORIGIN, cookieOrigin); } } ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/RequestAuthCache.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/RequestAuthCach0100644 0000000 0000000 00000012262 12301751676 032520 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthProtocolState; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthState; import org.apache.http.auth.Credentials; import org.apache.http.client.AuthCache; import org.apache.http.client.CredentialsProvider; import org.apache.http.conn.routing.RouteInfo; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Request interceptor that can preemptively authenticate against known hosts, * if there is a cached {@link AuthScheme} instance in the local * {@link AuthCache} associated with the given target or proxy host. * * @since 4.1 */ @Immutable public class RequestAuthCache implements HttpRequestInterceptor { private final Log log = LogFactory.getLog(getClass()); public RequestAuthCache() { super(); } public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { Args.notNull(request, "HTTP request"); Args.notNull(context, "HTTP context"); final HttpClientContext clientContext = HttpClientContext.adapt(context); final AuthCache authCache = clientContext.getAuthCache(); if (authCache == null) { this.log.debug("Auth cache not set in the context"); return; } final CredentialsProvider credsProvider = clientContext.getCredentialsProvider(); if (credsProvider == null) { this.log.debug("Credentials provider not set in the context"); return; } final RouteInfo route = clientContext.getHttpRoute(); HttpHost target = clientContext.getTargetHost(); if (target.getPort() < 0) { target = new HttpHost( target.getHostName(), route.getTargetHost().getPort(), target.getSchemeName()); } final AuthState targetState = clientContext.getTargetAuthState(); if (targetState != null && targetState.getState() == AuthProtocolState.UNCHALLENGED) { final AuthScheme authScheme = authCache.get(target); if (authScheme != null) { doPreemptiveAuth(target, authScheme, targetState, credsProvider); } } final HttpHost proxy = route.getProxyHost(); final AuthState proxyState = clientContext.getProxyAuthState(); if (proxy != null && proxyState != null && proxyState.getState() == AuthProtocolState.UNCHALLENGED) { final AuthScheme authScheme = authCache.get(proxy); if (authScheme != null) { doPreemptiveAuth(proxy, authScheme, proxyState, credsProvider); } } } private void doPreemptiveAuth( final HttpHost host, final AuthScheme authScheme, final AuthState authState, final CredentialsProvider credsProvider) { final String schemeName = authScheme.getSchemeName(); if (this.log.isDebugEnabled()) { this.log.debug("Re-using cached '" + schemeName + "' auth scheme for " + host); } final AuthScope authScope = new AuthScope(host, AuthScope.ANY_REALM, schemeName); final Credentials creds = credsProvider.getCredentials(authScope); if (creds != null) { if ("BASIC".equalsIgnoreCase(authScheme.getSchemeName())) { authState.setState(AuthProtocolState.CHALLENGED); } else { authState.setState(AuthProtocolState.SUCCESS); } authState.update(authScheme, creds); } else { this.log.debug("No credentials for preemptive authentication"); } } } ././@LongLink0100644 0000000 0000000 00000000163 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/RequestClientConnControl.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/RequestClientCo0100644 0000000 0000000 00000006524 12301751676 032544 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.annotation.Immutable; import org.apache.http.conn.routing.RouteInfo; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * This protocol interceptor is responsible for adding Connection * or Proxy-Connection headers to the outgoing requests, which * is essential for managing persistence of HTTP/1.0 connections. * * @since 4.0 */ @Immutable public class RequestClientConnControl implements HttpRequestInterceptor { private final Log log = LogFactory.getLog(getClass()); private static final String PROXY_CONN_DIRECTIVE = "Proxy-Connection"; public RequestClientConnControl() { super(); } public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { Args.notNull(request, "HTTP request"); final String method = request.getRequestLine().getMethod(); if (method.equalsIgnoreCase("CONNECT")) { request.setHeader(PROXY_CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); return; } final HttpClientContext clientContext = HttpClientContext.adapt(context); // Obtain the client connection (required) final RouteInfo route = clientContext.getHttpRoute(); if (route == null) { this.log.debug("Connection route not set in the context"); return; } if (route.getHopCount() == 1 || route.isTunnelled()) { if (!request.containsHeader(HTTP.CONN_DIRECTIVE)) { request.addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); } } if (route.getHopCount() == 2 && !route.isTunnelled()) { if (!request.containsHeader(PROXY_CONN_DIRECTIVE)) { request.addHeader(PROXY_CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); } } } } ././@LongLink0100644 0000000 0000000 00000000160 12302131604 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/RequestDefaultHeaders.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/RequestDefaultH0100644 0000000 0000000 00000005574 12301751676 032544 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.io.IOException; import java.util.Collection; import org.apache.http.Header; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.annotation.Immutable; import org.apache.http.client.params.ClientPNames; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Request interceptor that adds default request headers. * * @since 4.0 */ @SuppressWarnings("deprecation") @Immutable public class RequestDefaultHeaders implements HttpRequestInterceptor { private final Collection defaultHeaders; /** * @since 4.3 */ public RequestDefaultHeaders(final Collection defaultHeaders) { super(); this.defaultHeaders = defaultHeaders; } public RequestDefaultHeaders() { this(null); } public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { Args.notNull(request, "HTTP request"); final String method = request.getRequestLine().getMethod(); if (method.equalsIgnoreCase("CONNECT")) { return; } // Add default headers @SuppressWarnings("unchecked") Collection defHeaders = (Collection) request.getParams().getParameter(ClientPNames.DEFAULT_HEADERS); if (defHeaders == null) { defHeaders = this.defaultHeaders; } if (defHeaders != null) { for (final Header defHeader : defHeaders) { request.addHeader(defHeader); } } } } ././@LongLink0100644 0000000 0000000 00000000160 12302131604 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/RequestExpectContinue.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/RequestExpectCo0100644 0000000 0000000 00000006276 12301751676 032562 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.io.IOException; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.HttpVersion; import org.apache.http.ProtocolVersion; import org.apache.http.annotation.Immutable; import org.apache.http.client.config.RequestConfig; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * RequestExpectContinue is responsible for enabling the 'expect-continue' * handshake by adding Expect header. *

* This interceptor takes into account {@link RequestConfig#isExpectContinueEnabled()} * setting. * * @since 4.3 */ @Immutable public class RequestExpectContinue implements HttpRequestInterceptor { public RequestExpectContinue() { super(); } public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { Args.notNull(request, "HTTP request"); if (!request.containsHeader(HTTP.EXPECT_DIRECTIVE)) { if (request instanceof HttpEntityEnclosingRequest) { final ProtocolVersion ver = request.getRequestLine().getProtocolVersion(); final HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity(); // Do not send the expect header if request body is known to be empty if (entity != null && entity.getContentLength() != 0 && !ver.lessEquals(HttpVersion.HTTP_1_0)) { final HttpClientContext clientContext = HttpClientContext.adapt(context); final RequestConfig config = clientContext.getRequestConfig(); if (config.isExpectContinueEnabled()) { request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE); } } } } } } ././@LongLink0100644 0000000 0000000 00000000162 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/ResponseContentEncoding.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/ResponseContent0100644 0000000 0000000 00000010610 12301751676 032613 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.io.IOException; import java.util.Locale; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseInterceptor; import org.apache.http.annotation.Immutable; import org.apache.http.client.entity.DeflateDecompressingEntity; import org.apache.http.client.entity.GzipDecompressingEntity; import org.apache.http.protocol.HttpContext; /** * {@link HttpResponseInterceptor} responsible for processing Content-Encoding * responses. *

* Instances of this class are stateless and immutable, therefore threadsafe. * * @since 4.1 * */ @Immutable public class ResponseContentEncoding implements HttpResponseInterceptor { public static final String UNCOMPRESSED = "http.client.response.uncompressed"; /** * Handles the following {@code Content-Encoding}s by * using the appropriate decompressor to wrap the response Entity: *

    *
  • gzip - see {@link GzipDecompressingEntity}
  • *
  • deflate - see {@link DeflateDecompressingEntity}
  • *
  • identity - no action needed
  • *
* * @param response the response which contains the entity * @param context not currently used * * @throws HttpException if the {@code Content-Encoding} is none of the above */ public void process( final HttpResponse response, final HttpContext context) throws HttpException, IOException { final HttpEntity entity = response.getEntity(); // entity can be null in case of 304 Not Modified, 204 No Content or similar // check for zero length entity. if (entity != null && entity.getContentLength() != 0) { final Header ceheader = entity.getContentEncoding(); if (ceheader != null) { final HeaderElement[] codecs = ceheader.getElements(); boolean uncompressed = false; for (final HeaderElement codec : codecs) { final String codecname = codec.getName().toLowerCase(Locale.US); if ("gzip".equals(codecname) || "x-gzip".equals(codecname)) { response.setEntity(new GzipDecompressingEntity(response.getEntity())); uncompressed = true; break; } else if ("deflate".equals(codecname)) { response.setEntity(new DeflateDecompressingEntity(response.getEntity())); uncompressed = true; break; } else if ("identity".equals(codecname)) { /* Don't need to transform the content - no-op */ return; } else { throw new HttpException("Unsupported Content-Coding: " + codec.getName()); } } if (uncompressed) { response.removeHeaders("Content-Length"); response.removeHeaders("Content-Encoding"); response.removeHeaders("Content-MD5"); } } } } } ././@LongLink0100644 0000000 0000000 00000000161 12302131604 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/ResponseProcessCookies.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/protocol/ResponseProcess0100644 0000000 0000000 00000013550 12301751676 032625 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.io.IOException; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HeaderIterator; import org.apache.http.HttpException; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseInterceptor; import org.apache.http.annotation.Immutable; import org.apache.http.client.CookieStore; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SM; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Response interceptor that populates the current {@link CookieStore} with data * contained in response cookies received in the given the HTTP response. * * @since 4.0 */ @Immutable public class ResponseProcessCookies implements HttpResponseInterceptor { private final Log log = LogFactory.getLog(getClass()); public ResponseProcessCookies() { super(); } public void process(final HttpResponse response, final HttpContext context) throws HttpException, IOException { Args.notNull(response, "HTTP request"); Args.notNull(context, "HTTP context"); final HttpClientContext clientContext = HttpClientContext.adapt(context); // Obtain actual CookieSpec instance final CookieSpec cookieSpec = clientContext.getCookieSpec(); if (cookieSpec == null) { this.log.debug("Cookie spec not specified in HTTP context"); return; } // Obtain cookie store final CookieStore cookieStore = clientContext.getCookieStore(); if (cookieStore == null) { this.log.debug("Cookie store not specified in HTTP context"); return; } // Obtain actual CookieOrigin instance final CookieOrigin cookieOrigin = clientContext.getCookieOrigin(); if (cookieOrigin == null) { this.log.debug("Cookie origin not specified in HTTP context"); return; } HeaderIterator it = response.headerIterator(SM.SET_COOKIE); processCookies(it, cookieSpec, cookieOrigin, cookieStore); // see if the cookie spec supports cookie versioning. if (cookieSpec.getVersion() > 0) { // process set-cookie2 headers. // Cookie2 will replace equivalent Cookie instances it = response.headerIterator(SM.SET_COOKIE2); processCookies(it, cookieSpec, cookieOrigin, cookieStore); } } private void processCookies( final HeaderIterator iterator, final CookieSpec cookieSpec, final CookieOrigin cookieOrigin, final CookieStore cookieStore) { while (iterator.hasNext()) { final Header header = iterator.nextHeader(); try { final List cookies = cookieSpec.parse(header, cookieOrigin); for (final Cookie cookie : cookies) { try { cookieSpec.validate(cookie, cookieOrigin); cookieStore.addCookie(cookie); if (this.log.isDebugEnabled()) { this.log.debug("Cookie accepted [" + formatCooke(cookie) + "]"); } } catch (final MalformedCookieException ex) { if (this.log.isWarnEnabled()) { this.log.warn("Cookie rejected [" + formatCooke(cookie) + "] " + ex.getMessage()); } } } } catch (final MalformedCookieException ex) { if (this.log.isWarnEnabled()) { this.log.warn("Invalid cookie header: \"" + header + "\". " + ex.getMessage()); } } } } private static String formatCooke(final Cookie cookie) { final StringBuilder buf = new StringBuilder(); buf.append(cookie.getName()); buf.append("=\""); String v = cookie.getValue(); if (v.length() > 100) { v = v.substring(0, 100) + "..."; } buf.append(v); buf.append("\""); buf.append(", version:"); buf.append(Integer.toString(cookie.getVersion())); buf.append(", domain:"); buf.append(cookie.getDomain()); buf.append(", path:"); buf.append(cookie.getPath()); buf.append(", expiry:"); buf.append(cookie.getExpiryDate()); return buf.toString(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/utils/0040755 0000000 0000000 00000000000 12301751675 027042 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/utils/CloneUtils.java0100644 0000000 0000000 00000005710 12301751675 031766 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.http.annotation.Immutable; /** * A collection of utilities to workaround limitations of Java clone framework. * * @since 4.0 */ @Immutable public class CloneUtils { /** * @since 4.3 */ public static T cloneObject(final T obj) throws CloneNotSupportedException { if (obj == null) { return null; } if (obj instanceof Cloneable) { final Class clazz = obj.getClass (); final Method m; try { m = clazz.getMethod("clone", (Class[]) null); } catch (final NoSuchMethodException ex) { throw new NoSuchMethodError(ex.getMessage()); } try { @SuppressWarnings("unchecked") // OK because clone() preserves the class final T result = (T) m.invoke(obj, (Object []) null); return result; } catch (final InvocationTargetException ex) { final Throwable cause = ex.getCause(); if (cause instanceof CloneNotSupportedException) { throw ((CloneNotSupportedException) cause); } else { throw new Error("Unexpected exception", cause); } } catch (final IllegalAccessException ex) { throw new IllegalAccessError(ex.getMessage()); } } else { throw new CloneNotSupportedException(); } } public static Object clone(final Object obj) throws CloneNotSupportedException { return cloneObject(obj); } /** * This class should not be instantiated. */ private CloneUtils() { } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/utils/DateUtils.java0100644 0000000 0000000 00000021415 12301751675 031603 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import java.lang.ref.SoftReference; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.TimeZone; import org.apache.http.annotation.Immutable; import org.apache.http.util.Args; /** * A utility class for parsing and formatting HTTP dates as used in cookies and * other headers. This class handles dates as defined by RFC 2616 section * 3.3.1 as well as some other common non-standard formats. * * @since 4.3 */ @Immutable public final class DateUtils { /** * Date format pattern used to parse HTTP date headers in RFC 1123 format. */ public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz"; /** * Date format pattern used to parse HTTP date headers in RFC 1036 format. */ public static final String PATTERN_RFC1036 = "EEE, dd-MMM-yy HH:mm:ss zzz"; /** * Date format pattern used to parse HTTP date headers in ANSI C * asctime() format. */ public static final String PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy"; private static final String[] DEFAULT_PATTERNS = new String[] { PATTERN_RFC1123, PATTERN_RFC1036, PATTERN_ASCTIME }; private static final Date DEFAULT_TWO_DIGIT_YEAR_START; public static final TimeZone GMT = TimeZone.getTimeZone("GMT"); static { final Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(GMT); calendar.set(2000, Calendar.JANUARY, 1, 0, 0, 0); calendar.set(Calendar.MILLISECOND, 0); DEFAULT_TWO_DIGIT_YEAR_START = calendar.getTime(); } /** * Parses a date value. The formats used for parsing the date value are retrieved from * the default http params. * * @param dateValue the date value to parse * * @return the parsed date or null if input could not be parsed */ public static Date parseDate(final String dateValue) { return parseDate(dateValue, null, null); } /** * Parses the date value using the given date formats. * * @param dateValue the date value to parse * @param dateFormats the date formats to use * * @return the parsed date or null if input could not be parsed */ public static Date parseDate(final String dateValue, final String[] dateFormats) { return parseDate(dateValue, dateFormats, null); } /** * Parses the date value using the given date formats. * * @param dateValue the date value to parse * @param dateFormats the date formats to use * @param startDate During parsing, two digit years will be placed in the range * startDate to startDate + 100 years. This value may * be null. When null is given as a parameter, year * 2000 will be used. * * @return the parsed date or null if input could not be parsed */ public static Date parseDate( final String dateValue, final String[] dateFormats, final Date startDate) { Args.notNull(dateValue, "Date value"); final String[] localDateFormats = dateFormats != null ? dateFormats : DEFAULT_PATTERNS; final Date localStartDate = startDate != null ? startDate : DEFAULT_TWO_DIGIT_YEAR_START; String v = dateValue; // trim single quotes around date if present // see issue #5279 if (v.length() > 1 && v.startsWith("'") && v.endsWith("'")) { v = v.substring (1, v.length() - 1); } for (final String dateFormat : localDateFormats) { final SimpleDateFormat dateParser = DateFormatHolder.formatFor(dateFormat); dateParser.set2DigitYearStart(localStartDate); final ParsePosition pos = new ParsePosition(0); final Date result = dateParser.parse(v, pos); if (pos.getIndex() != 0) { return result; } } return null; } /** * Formats the given date according to the RFC 1123 pattern. * * @param date The date to format. * @return An RFC 1123 formatted date string. * * @see #PATTERN_RFC1123 */ public static String formatDate(final Date date) { return formatDate(date, PATTERN_RFC1123); } /** * Formats the given date according to the specified pattern. The pattern * must conform to that used by the {@link SimpleDateFormat simple date * format} class. * * @param date The date to format. * @param pattern The pattern to use for formatting the date. * @return A formatted date string. * * @throws IllegalArgumentException If the given date pattern is invalid. * * @see SimpleDateFormat */ public static String formatDate(final Date date, final String pattern) { Args.notNull(date, "Date"); Args.notNull(pattern, "Pattern"); final SimpleDateFormat formatter = DateFormatHolder.formatFor(pattern); return formatter.format(date); } /** * Clears thread-local variable containing {@link java.text.DateFormat} cache. * * @since 4.3 */ public static void clearThreadLocal() { DateFormatHolder.clearThreadLocal(); } /** This class should not be instantiated. */ private DateUtils() { } /** * A factory for {@link SimpleDateFormat}s. The instances are stored in a * threadlocal way because SimpleDateFormat is not threadsafe as noted in * {@link SimpleDateFormat its javadoc}. * */ final static class DateFormatHolder { private static final ThreadLocal>> THREADLOCAL_FORMATS = new ThreadLocal>>() { @Override protected SoftReference> initialValue() { return new SoftReference>( new HashMap()); } }; /** * creates a {@link SimpleDateFormat} for the requested format string. * * @param pattern * a non-null format String according to * {@link SimpleDateFormat}. The format is not checked against * null since all paths go through * {@link DateUtils}. * @return the requested format. This simple dateformat should not be used * to {@link SimpleDateFormat#applyPattern(String) apply} to a * different pattern. */ public static SimpleDateFormat formatFor(final String pattern) { final SoftReference> ref = THREADLOCAL_FORMATS.get(); Map formats = ref.get(); if (formats == null) { formats = new HashMap(); THREADLOCAL_FORMATS.set( new SoftReference>(formats)); } SimpleDateFormat format = formats.get(pattern); if (format == null) { format = new SimpleDateFormat(pattern, Locale.US); format.setTimeZone(TimeZone.getTimeZone("GMT")); formats.put(pattern, format); } return format; } public static void clearThreadLocal() { THREADLOCAL_FORMATS.remove(); } } } ././@LongLink0100644 0000000 0000000 00000000147 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/utils/HttpClientUtils.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/utils/HttpClientUtils.ja0100644 0000000 0000000 00000010425 12301751675 032454 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import java.io.Closeable; import java.io.IOException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.util.EntityUtils; /** * Convenience methods for closing response and client objects. * * @since 4.2 */ public class HttpClientUtils { private HttpClientUtils() { } /** * Unconditionally close a response. *

* Example Code: * *

     * HttpResponse httpResponse = null;
     * try {
     *     httpResponse = httpClient.execute(httpGet);
     * } catch (Exception e) {
     *     // error handling
     * } finally {
     *     HttpClientUtils.closeQuietly(httpResponse);
     * }
     * 
* * @param response * the HttpResponse to release resources, may be null or already * closed. * * @since 4.2 */ public static void closeQuietly(final HttpResponse response) { if (response != null) { final HttpEntity entity = response.getEntity(); if (entity != null) { try { EntityUtils.consume(entity); } catch (final IOException ex) { } } } } /** * Unconditionally close a response. *

* Example Code: * *

     * HttpResponse httpResponse = null;
     * try {
     *     httpResponse = httpClient.execute(httpGet);
     * } catch (Exception e) {
     *     // error handling
     * } finally {
     *     HttpClientUtils.closeQuietly(httpResponse);
     * }
     * 
* * @param response * the HttpResponse to release resources, may be null or already * closed. * * @since 4.3 */ public static void closeQuietly(final CloseableHttpResponse response) { if (response != null) { try { try { EntityUtils.consume(response.getEntity()); } finally { response.close(); } } catch (final IOException ignore) { } } } /** * Unconditionally close a httpClient. Shuts down the underlying connection * manager and releases the resources. *

* Example Code: * *

     * HttpClient httpClient = HttpClients.createDefault();
     * try {
     *   httpClient.execute(request);
     * } catch (Exception e) {
     *   // error handling
     * } finally {
     *   HttpClientUtils.closeQuietly(httpClient);
     * }
     * 
* * @param httpClient * the HttpClient to close, may be null or already closed. * @since 4.2 */ public static void closeQuietly(final HttpClient httpClient) { if (httpClient != null) { if (httpClient instanceof Closeable) { try { ((Closeable) httpClient).close(); } catch (final IOException ignore) { } } } } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/utils/Idn.java0100644 0000000 0000000 00000003137 12301751675 030420 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; /** * Abstraction of international domain name (IDN) conversion. * * @since 4.0 */ public interface Idn { /** * Converts a name from its punycode representation to Unicode. * The name may be a single hostname or a dot-separated qualified domain name. * @param punycode the Punycode representation * @return the Unicode domain name */ String toUnicode(String punycode); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/utils/JdkIdn.java0100644 0000000 0000000 00000004741 12301751675 031053 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.http.annotation.Immutable; /** * Uses the java.net.IDN class through reflection. * * @since 4.0 */ @Immutable public class JdkIdn implements Idn { private final Method toUnicode; /** * * @throws ClassNotFoundException if java.net.IDN is not available */ public JdkIdn() throws ClassNotFoundException { final Class clazz = Class.forName("java.net.IDN"); try { toUnicode = clazz.getMethod("toUnicode", String.class); } catch (final SecurityException e) { // doesn't happen throw new IllegalStateException(e.getMessage(), e); } catch (final NoSuchMethodException e) { // doesn't happen throw new IllegalStateException(e.getMessage(), e); } } public String toUnicode(final String punycode) { try { return (String) toUnicode.invoke(null, punycode); } catch (final IllegalAccessException e) { throw new IllegalStateException(e.getMessage(), e); } catch (final InvocationTargetException e) { final Throwable t = e.getCause(); throw new RuntimeException(t.getMessage(), t); } } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/utils/package-info.java0100644 0000000 0000000 00000002352 12301751675 032230 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Client utility classes. */ package org.apache.http.client.utils; httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/utils/Punycode.java0100644 0000000 0000000 00000003401 12301751675 031466 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import org.apache.http.annotation.Immutable; /** * Facade that provides conversion between Unicode and Punycode domain names. * It will use an appropriate implementation. * * @since 4.0 */ @Immutable public class Punycode { private static final Idn impl; static { Idn _impl; try { _impl = new JdkIdn(); } catch (final Exception e) { _impl = new Rfc3492Idn(); } impl = _impl; } public static String toUnicode(final String punycode) { return impl.toUnicode(punycode); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/utils/Rfc3492Idn.java0100644 0000000 0000000 00000011274 12301751675 031376 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import java.util.StringTokenizer; import org.apache.http.annotation.Immutable; /** * Implementation from pseudo code in RFC 3492. * * @since 4.0 */ @Immutable public class Rfc3492Idn implements Idn { private static final int base = 36; private static final int tmin = 1; private static final int tmax = 26; private static final int skew = 38; private static final int damp = 700; private static final int initial_bias = 72; private static final int initial_n = 128; private static final char delimiter = '-'; private static final String ACE_PREFIX = "xn--"; private int adapt(final int delta, final int numpoints, final boolean firsttime) { int d = delta; if (firsttime) { d = d / damp; } else { d = d / 2; } d = d + (d / numpoints); int k = 0; while (d > ((base - tmin) * tmax) / 2) { d = d / (base - tmin); k = k + base; } return k + (((base - tmin + 1) * d) / (d + skew)); } private int digit(final char c) { if ((c >= 'A') && (c <= 'Z')) { return (c - 'A'); } if ((c >= 'a') && (c <= 'z')) { return (c - 'a'); } if ((c >= '0') && (c <= '9')) { return (c - '0') + 26; } throw new IllegalArgumentException("illegal digit: "+ c); } public String toUnicode(final String punycode) { final StringBuilder unicode = new StringBuilder(punycode.length()); final StringTokenizer tok = new StringTokenizer(punycode, "."); while (tok.hasMoreTokens()) { String t = tok.nextToken(); if (unicode.length() > 0) { unicode.append('.'); } if (t.startsWith(ACE_PREFIX)) { t = decode(t.substring(4)); } unicode.append(t); } return unicode.toString(); } protected String decode(final String s) { String input = s; int n = initial_n; int i = 0; int bias = initial_bias; final StringBuilder output = new StringBuilder(input.length()); final int lastdelim = input.lastIndexOf(delimiter); if (lastdelim != -1) { output.append(input.subSequence(0, lastdelim)); input = input.substring(lastdelim + 1); } while (input.length() > 0) { final int oldi = i; int w = 1; for (int k = base;; k += base) { if (input.length() == 0) { break; } final char c = input.charAt(0); input = input.substring(1); final int digit = digit(c); i = i + digit * w; // FIXME fail on overflow final int t; if (k <= bias + tmin) { t = tmin; } else if (k >= bias + tmax) { t = tmax; } else { t = k - bias; } if (digit < t) { break; } w = w * (base - t); // FIXME fail on overflow } bias = adapt(i - oldi, output.length() + 1, (oldi == 0)); n = n + i / (output.length() + 1); // FIXME fail on overflow i = i % (output.length() + 1); // {if n is a basic code point then fail} output.insert(i, (char) n); i++; } return output.toString(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/utils/URIBuilder.java0100644 0000000 0000000 00000035375 12301751675 031665 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.http.Consts; import org.apache.http.NameValuePair; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.conn.util.InetAddressUtils; import org.apache.http.message.BasicNameValuePair; /** * Builder for {@link URI} instances. * * @since 4.2 */ @NotThreadSafe public class URIBuilder { private String scheme; private String encodedSchemeSpecificPart; private String encodedAuthority; private String userInfo; private String encodedUserInfo; private String host; private int port; private String path; private String encodedPath; private String encodedQuery; private List queryParams; private String query; private String fragment; private String encodedFragment; /** * Constructs an empty instance. */ public URIBuilder() { super(); this.port = -1; } /** * Construct an instance from the string which must be a valid URI. * * @param string a valid URI in string form * @throws URISyntaxException if the input is not a valid URI */ public URIBuilder(final String string) throws URISyntaxException { super(); digestURI(new URI(string)); } /** * Construct an instance from the provided URI. * @param uri */ public URIBuilder(final URI uri) { super(); digestURI(uri); } private List parseQuery(final String query, final Charset charset) { if (query != null && query.length() > 0) { return URLEncodedUtils.parse(query, charset); } return null; } /** * Builds a {@link URI} instance. */ public URI build() throws URISyntaxException { return new URI(buildString()); } private String buildString() { final StringBuilder sb = new StringBuilder(); if (this.scheme != null) { sb.append(this.scheme).append(':'); } if (this.encodedSchemeSpecificPart != null) { sb.append(this.encodedSchemeSpecificPart); } else { if (this.encodedAuthority != null) { sb.append("//").append(this.encodedAuthority); } else if (this.host != null) { sb.append("//"); if (this.encodedUserInfo != null) { sb.append(this.encodedUserInfo).append("@"); } else if (this.userInfo != null) { sb.append(encodeUserInfo(this.userInfo)).append("@"); } if (InetAddressUtils.isIPv6Address(this.host)) { sb.append("[").append(this.host).append("]"); } else { sb.append(this.host); } if (this.port >= 0) { sb.append(":").append(this.port); } } if (this.encodedPath != null) { sb.append(normalizePath(this.encodedPath)); } else if (this.path != null) { sb.append(encodePath(normalizePath(this.path))); } if (this.encodedQuery != null) { sb.append("?").append(this.encodedQuery); } else if (this.queryParams != null) { sb.append("?").append(encodeUrlForm(this.queryParams)); } else if (this.query != null) { sb.append("?").append(encodeUric(this.query)); } } if (this.encodedFragment != null) { sb.append("#").append(this.encodedFragment); } else if (this.fragment != null) { sb.append("#").append(encodeUric(this.fragment)); } return sb.toString(); } private void digestURI(final URI uri) { this.scheme = uri.getScheme(); this.encodedSchemeSpecificPart = uri.getRawSchemeSpecificPart(); this.encodedAuthority = uri.getRawAuthority(); this.host = uri.getHost(); this.port = uri.getPort(); this.encodedUserInfo = uri.getRawUserInfo(); this.userInfo = uri.getUserInfo(); this.encodedPath = uri.getRawPath(); this.path = uri.getPath(); this.encodedQuery = uri.getRawQuery(); this.queryParams = parseQuery(uri.getRawQuery(), Consts.UTF_8); this.encodedFragment = uri.getRawFragment(); this.fragment = uri.getFragment(); } private String encodeUserInfo(final String userInfo) { return URLEncodedUtils.encUserInfo(userInfo, Consts.UTF_8); } private String encodePath(final String path) { return URLEncodedUtils.encPath(path, Consts.UTF_8); } private String encodeUrlForm(final List params) { return URLEncodedUtils.format(params, Consts.UTF_8); } private String encodeUric(final String fragment) { return URLEncodedUtils.encUric(fragment, Consts.UTF_8); } /** * Sets URI scheme. */ public URIBuilder setScheme(final String scheme) { this.scheme = scheme; return this; } /** * Sets URI user info. The value is expected to be unescaped and may contain non ASCII * characters. */ public URIBuilder setUserInfo(final String userInfo) { this.userInfo = userInfo; this.encodedSchemeSpecificPart = null; this.encodedAuthority = null; this.encodedUserInfo = null; return this; } /** * Sets URI user info as a combination of username and password. These values are expected to * be unescaped and may contain non ASCII characters. */ public URIBuilder setUserInfo(final String username, final String password) { return setUserInfo(username + ':' + password); } /** * Sets URI host. */ public URIBuilder setHost(final String host) { this.host = host; this.encodedSchemeSpecificPart = null; this.encodedAuthority = null; return this; } /** * Sets URI port. */ public URIBuilder setPort(final int port) { this.port = port < 0 ? -1 : port; this.encodedSchemeSpecificPart = null; this.encodedAuthority = null; return this; } /** * Sets URI path. The value is expected to be unescaped and may contain non ASCII characters. */ public URIBuilder setPath(final String path) { this.path = path; this.encodedSchemeSpecificPart = null; this.encodedPath = null; return this; } /** * Removes URI query. */ public URIBuilder removeQuery() { this.queryParams = null; this.query = null; this.encodedQuery = null; this.encodedSchemeSpecificPart = null; return this; } /** * Sets URI query. *

* The value is expected to be encoded form data. * * @deprecated (4.3) use {@link #setParameters(List)} or {@link #setParameters(NameValuePair...)} * * @see URLEncodedUtils#parse */ @Deprecated public URIBuilder setQuery(final String query) { this.queryParams = parseQuery(query, Consts.UTF_8); this.query = null; this.encodedQuery = null; this.encodedSchemeSpecificPart = null; return this; } /** * Sets URI query parameters. The parameter name / values are expected to be unescaped * and may contain non ASCII characters. *

* Please note query parameters and custom query component are mutually exclusive. This method * will remove custom query if present. * * @since 4.3 */ public URIBuilder setParameters(final List nvps) { if (this.queryParams == null) { this.queryParams = new ArrayList(); } else { this.queryParams.clear(); } this.queryParams.addAll(nvps); this.encodedQuery = null; this.encodedSchemeSpecificPart = null; this.query = null; return this; } /** * Adds URI query parameters. The parameter name / values are expected to be unescaped * and may contain non ASCII characters. *

* Please note query parameters and custom query component are mutually exclusive. This method * will remove custom query if present. * * @since 4.3 */ public URIBuilder addParameters(final List nvps) { if (this.queryParams == null) { this.queryParams = new ArrayList(); } this.queryParams.addAll(nvps); this.encodedQuery = null; this.encodedSchemeSpecificPart = null; this.query = null; return this; } /** * Sets URI query parameters. The parameter name / values are expected to be unescaped * and may contain non ASCII characters. *

* Please note query parameters and custom query component are mutually exclusive. This method * will remove custom query if present. * * @since 4.3 */ public URIBuilder setParameters(final NameValuePair... nvps) { if (this.queryParams == null) { this.queryParams = new ArrayList(); } else { this.queryParams.clear(); } for (final NameValuePair nvp: nvps) { this.queryParams.add(nvp); } this.encodedQuery = null; this.encodedSchemeSpecificPart = null; this.query = null; return this; } /** * Adds parameter to URI query. The parameter name and value are expected to be unescaped * and may contain non ASCII characters. *

* Please note query parameters and custom query component are mutually exclusive. This method * will remove custom query if present. */ public URIBuilder addParameter(final String param, final String value) { if (this.queryParams == null) { this.queryParams = new ArrayList(); } this.queryParams.add(new BasicNameValuePair(param, value)); this.encodedQuery = null; this.encodedSchemeSpecificPart = null; this.query = null; return this; } /** * Sets parameter of URI query overriding existing value if set. The parameter name and value * are expected to be unescaped and may contain non ASCII characters. *

* Please note query parameters and custom query component are mutually exclusive. This method * will remove custom query if present. */ public URIBuilder setParameter(final String param, final String value) { if (this.queryParams == null) { this.queryParams = new ArrayList(); } if (!this.queryParams.isEmpty()) { for (final Iterator it = this.queryParams.iterator(); it.hasNext(); ) { final NameValuePair nvp = it.next(); if (nvp.getName().equals(param)) { it.remove(); } } } this.queryParams.add(new BasicNameValuePair(param, value)); this.encodedQuery = null; this.encodedSchemeSpecificPart = null; this.query = null; return this; } /** * Clears URI query parameters. * * @since 4.3 */ public URIBuilder clearParameters() { this.queryParams = null; this.encodedQuery = null; this.encodedSchemeSpecificPart = null; return this; } /** * Sets custom URI query. The value is expected to be unescaped and may contain non ASCII * characters. *

* Please note query parameters and custom query component are mutually exclusive. This method * will remove query parameters if present. * * @since 4.3 */ public URIBuilder setCustomQuery(final String query) { this.query = query; this.encodedQuery = null; this.encodedSchemeSpecificPart = null; this.queryParams = null; return this; } /** * Sets URI fragment. The value is expected to be unescaped and may contain non ASCII * characters. */ public URIBuilder setFragment(final String fragment) { this.fragment = fragment; this.encodedFragment = null; return this; } /** * @since 4.3 */ public boolean isAbsolute() { return this.scheme != null; } /** * @since 4.3 */ public boolean isOpaque() { return this.path == null; } public String getScheme() { return this.scheme; } public String getUserInfo() { return this.userInfo; } public String getHost() { return this.host; } public int getPort() { return this.port; } public String getPath() { return this.path; } public List getQueryParams() { if (this.queryParams != null) { return new ArrayList(this.queryParams); } else { return new ArrayList(); } } public String getFragment() { return this.fragment; } @Override public String toString() { return buildString(); } private static String normalizePath(final String path) { String s = path; if (s == null) { return null; } int n = 0; for (; n < s.length(); n++) { if (s.charAt(n) != '/') { break; } } if (n > 1) { s = s.substring(n - 1); } return s; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/utils/URIUtils.java0100644 0000000 0000000 00000037336 12301751675 031376 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import java.net.URI; import java.net.URISyntaxException; import java.util.List; import java.util.Locale; import java.util.Stack; import org.apache.http.HttpHost; import org.apache.http.annotation.Immutable; import org.apache.http.util.Args; import org.apache.http.util.TextUtils; /** * A collection of utilities for {@link URI URIs}, to workaround * bugs within the class or for ease-of-use features. * * @since 4.0 */ @Immutable public class URIUtils { /** * Constructs a {@link URI} using all the parameters. This should be * used instead of * {@link URI#URI(String, String, String, int, String, String, String)} * or any of the other URI multi-argument URI constructors. * * @param scheme * Scheme name * @param host * Host name * @param port * Port number * @param path * Path * @param query * Query * @param fragment * Fragment * * @throws URISyntaxException * If both a scheme and a path are given but the path is * relative, if the URI string constructed from the given * components violates RFC 2396, or if the authority * component of the string is present but cannot be parsed * as a server-based authority * * @deprecated (4.2) use {@link URIBuilder}. */ @Deprecated public static URI createURI( final String scheme, final String host, final int port, final String path, final String query, final String fragment) throws URISyntaxException { final StringBuilder buffer = new StringBuilder(); if (host != null) { if (scheme != null) { buffer.append(scheme); buffer.append("://"); } buffer.append(host); if (port > 0) { buffer.append(':'); buffer.append(port); } } if (path == null || !path.startsWith("/")) { buffer.append('/'); } if (path != null) { buffer.append(path); } if (query != null) { buffer.append('?'); buffer.append(query); } if (fragment != null) { buffer.append('#'); buffer.append(fragment); } return new URI(buffer.toString()); } /** * A convenience method for creating a new {@link URI} whose scheme, host * and port are taken from the target host, but whose path, query and * fragment are taken from the existing URI. The fragment is only used if * dropFragment is false. The path is set to "/" if not explicitly specified. * * @param uri * Contains the path, query and fragment to use. * @param target * Contains the scheme, host and port to use. * @param dropFragment * True if the fragment should not be copied. * * @throws URISyntaxException * If the resulting URI is invalid. */ public static URI rewriteURI( final URI uri, final HttpHost target, final boolean dropFragment) throws URISyntaxException { Args.notNull(uri, "URI"); if (uri.isOpaque()) { return uri; } final URIBuilder uribuilder = new URIBuilder(uri); if (target != null) { uribuilder.setScheme(target.getSchemeName()); uribuilder.setHost(target.getHostName()); uribuilder.setPort(target.getPort()); } else { uribuilder.setScheme(null); uribuilder.setHost(null); uribuilder.setPort(-1); } if (dropFragment) { uribuilder.setFragment(null); } if (TextUtils.isEmpty(uribuilder.getPath())) { uribuilder.setPath("/"); } return uribuilder.build(); } /** * A convenience method for * {@link URIUtils#rewriteURI(URI, HttpHost, boolean)} that always keeps the * fragment. */ public static URI rewriteURI( final URI uri, final HttpHost target) throws URISyntaxException { return rewriteURI(uri, target, false); } /** * A convenience method that creates a new {@link URI} whose scheme, host, port, path, * query are taken from the existing URI, dropping any fragment or user-information. * The path is set to "/" if not explicitly specified. The existing URI is returned * unmodified if it has no fragment or user-information and has a path. * * @param uri * original URI. * @throws URISyntaxException * If the resulting URI is invalid. */ public static URI rewriteURI(final URI uri) throws URISyntaxException { Args.notNull(uri, "URI"); if (uri.isOpaque()) { return uri; } final URIBuilder uribuilder = new URIBuilder(uri); if (uribuilder.getUserInfo() != null) { uribuilder.setUserInfo(null); } if (TextUtils.isEmpty(uribuilder.getPath())) { uribuilder.setPath("/"); } if (uribuilder.getHost() != null) { uribuilder.setHost(uribuilder.getHost().toLowerCase(Locale.ENGLISH)); } uribuilder.setFragment(null); return uribuilder.build(); } /** * Resolves a URI reference against a base URI. Work-around for bug in * java.net.URI () * * @param baseURI the base URI * @param reference the URI reference * @return the resulting URI */ public static URI resolve(final URI baseURI, final String reference) { return URIUtils.resolve(baseURI, URI.create(reference)); } /** * Resolves a URI reference against a base URI. Work-around for bugs in * java.net.URI (e.g. ) * * @param baseURI the base URI * @param reference the URI reference * @return the resulting URI */ public static URI resolve(final URI baseURI, final URI reference){ Args.notNull(baseURI, "Base URI"); Args.notNull(reference, "Reference URI"); URI ref = reference; final String s = ref.toString(); if (s.startsWith("?")) { return resolveReferenceStartingWithQueryString(baseURI, ref); } final boolean emptyReference = s.length() == 0; if (emptyReference) { ref = URI.create("#"); } URI resolved = baseURI.resolve(ref); if (emptyReference) { final String resolvedString = resolved.toString(); resolved = URI.create(resolvedString.substring(0, resolvedString.indexOf('#'))); } return normalizeSyntax(resolved); } /** * Resolves a reference starting with a query string. * * @param baseURI the base URI * @param reference the URI reference starting with a query string * @return the resulting URI */ private static URI resolveReferenceStartingWithQueryString( final URI baseURI, final URI reference) { String baseUri = baseURI.toString(); baseUri = baseUri.indexOf('?') > -1 ? baseUri.substring(0, baseUri.indexOf('?')) : baseUri; return URI.create(baseUri + reference.toString()); } /** * Removes dot segments according to RFC 3986, section 5.2.4 and * Syntax-Based Normalization according to RFC 3986, section 6.2.2. * * @param uri the original URI * @return the URI without dot segments */ private static URI normalizeSyntax(final URI uri) { if (uri.isOpaque() || uri.getAuthority() == null) { // opaque and file: URIs return uri; } Args.check(uri.isAbsolute(), "Base URI must be absolute"); final String path = uri.getPath() == null ? "" : uri.getPath(); final String[] inputSegments = path.split("/"); final Stack outputSegments = new Stack(); for (final String inputSegment : inputSegments) { if ((inputSegment.length() == 0) || (".".equals(inputSegment))) { // Do nothing } else if ("..".equals(inputSegment)) { if (!outputSegments.isEmpty()) { outputSegments.pop(); } } else { outputSegments.push(inputSegment); } } final StringBuilder outputBuffer = new StringBuilder(); for (final String outputSegment : outputSegments) { outputBuffer.append('/').append(outputSegment); } if (path.lastIndexOf('/') == path.length() - 1) { // path.endsWith("/") || path.equals("") outputBuffer.append('/'); } try { final String scheme = uri.getScheme().toLowerCase(); final String auth = uri.getAuthority().toLowerCase(); final URI ref = new URI(scheme, auth, outputBuffer.toString(), null, null); if (uri.getQuery() == null && uri.getFragment() == null) { return ref; } final StringBuilder normalized = new StringBuilder( ref.toASCIIString()); if (uri.getQuery() != null) { // query string passed through unchanged normalized.append('?').append(uri.getRawQuery()); } if (uri.getFragment() != null) { // fragment passed through unchanged normalized.append('#').append(uri.getRawFragment()); } return URI.create(normalized.toString()); } catch (final URISyntaxException e) { throw new IllegalArgumentException(e); } } /** * Extracts target host from the given {@link URI}. * * @param uri * @return the target host if the URI is absolute or null if the URI is * relative or does not contain a valid host name. * * @since 4.1 */ public static HttpHost extractHost(final URI uri) { if (uri == null) { return null; } HttpHost target = null; if (uri.isAbsolute()) { int port = uri.getPort(); // may be overridden later String host = uri.getHost(); if (host == null) { // normal parse failed; let's do it ourselves // authority does not seem to care about the valid character-set for host names host = uri.getAuthority(); if (host != null) { // Strip off any leading user credentials final int at = host.indexOf('@'); if (at >= 0) { if (host.length() > at+1 ) { host = host.substring(at+1); } else { host = null; // @ on its own } } // Extract the port suffix, if present if (host != null) { final int colon = host.indexOf(':'); if (colon >= 0) { final int pos = colon + 1; int len = 0; for (int i = pos; i < host.length(); i++) { if (Character.isDigit(host.charAt(i))) { len++; } else { break; } } if (len > 0) { try { port = Integer.parseInt(host.substring(pos, pos + len)); } catch (final NumberFormatException ex) { } } host = host.substring(0, colon); } } } } final String scheme = uri.getScheme(); if (host != null) { target = new HttpHost(host, port, scheme); } } return target; } /** * Derives the interpreted (absolute) URI that was used to generate the last * request. This is done by extracting the request-uri and target origin for * the last request and scanning all the redirect locations for the last * fragment identifier, then combining the result into a {@link URI}. * * @param originalURI * original request before any redirects * @param target * if the last URI is relative, it is resolved against this target, * or null if not available. * @param redirects * collection of redirect locations since the original request * or null if not available. * @return interpreted (absolute) URI */ public static URI resolve( final URI originalURI, final HttpHost target, final List redirects) throws URISyntaxException { Args.notNull(originalURI, "Request URI"); final URIBuilder uribuilder; if (redirects == null || redirects.isEmpty()) { uribuilder = new URIBuilder(originalURI); } else { uribuilder = new URIBuilder(redirects.get(redirects.size() - 1)); String frag = uribuilder.getFragment(); // read interpreted fragment identifier from redirect locations for (int i = redirects.size() - 1; frag == null && i >= 0; i--) { frag = redirects.get(i).getFragment(); } uribuilder.setFragment(frag); } // read interpreted fragment identifier from original request if (uribuilder.getFragment() == null) { uribuilder.setFragment(originalURI.getFragment()); } // last target origin if (target != null && !uribuilder.isAbsolute()) { uribuilder.setScheme(target.getSchemeName()); uribuilder.setHost(target.getHostName()); uribuilder.setPort(target.getPort()); } return uribuilder.build(); } /** * This class should not be instantiated. */ private URIUtils() { } } ././@LongLink0100644 0000000 0000000 00000000147 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/utils/URLEncodedUtils.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/client/utils/URLEncodedUtils.ja0100644 0000000 0000000 00000056004 12301751675 032325 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import java.io.IOException; import java.net.URI; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.BitSet; import java.util.Collections; import java.util.List; import java.util.Scanner; import org.apache.http.Consts; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.annotation.Immutable; import org.apache.http.entity.ContentType; import org.apache.http.message.BasicHeaderValueParser; import org.apache.http.message.BasicNameValuePair; import org.apache.http.message.ParserCursor; import org.apache.http.protocol.HTTP; import org.apache.http.util.CharArrayBuffer; import org.apache.http.util.EntityUtils; /** * A collection of utilities for encoding URLs. * * @since 4.0 */ @Immutable public class URLEncodedUtils { /** * The default HTML form content type. */ public static final String CONTENT_TYPE = "application/x-www-form-urlencoded"; private static final char QP_SEP_A = '&'; private static final char QP_SEP_S = ';'; private static final String NAME_VALUE_SEPARATOR = "="; /** * Returns a list of {@link NameValuePair NameValuePairs} as built from the URI's query portion. For example, a URI * of http://example.org/path/to/file?a=1&b=2&c=3 would return a list of three NameValuePairs, one for a=1, one for * b=2, and one for c=3. By convention, {@code '&'} and {@code ';'} are accepted as parameter separators. *

* This is typically useful while parsing an HTTP PUT. * * This API is currently only used for testing. * * @param uri * URI to parse * @param charset * Charset name to use while parsing the query * @return a list of {@link NameValuePair} as built from the URI's query portion. */ public static List parse(final URI uri, final String charset) { final String query = uri.getRawQuery(); if (query != null && query.length() > 0) { final List result = new ArrayList(); final Scanner scanner = new Scanner(query); parse(result, scanner, QP_SEP_PATTERN, charset); return result; } return Collections.emptyList(); } /** * Returns a list of {@link NameValuePair NameValuePairs} as parsed from an {@link HttpEntity}. The encoding is * taken from the entity's Content-Encoding header. *

* This is typically used while parsing an HTTP POST. * * @param entity * The entity to parse * @return a list of {@link NameValuePair} as built from the URI's query portion. * @throws IOException * If there was an exception getting the entity's data. */ public static List parse( final HttpEntity entity) throws IOException { final ContentType contentType = ContentType.get(entity); if (contentType != null && contentType.getMimeType().equalsIgnoreCase(CONTENT_TYPE)) { final String content = EntityUtils.toString(entity, Consts.ASCII); if (content != null && content.length() > 0) { Charset charset = contentType.getCharset(); if (charset == null) { charset = HTTP.DEF_CONTENT_CHARSET; } return parse(content, charset, QP_SEPS); } } return Collections.emptyList(); } /** * Returns true if the entity's Content-Type header is * application/x-www-form-urlencoded. */ public static boolean isEncoded(final HttpEntity entity) { final Header h = entity.getContentType(); if (h != null) { final HeaderElement[] elems = h.getElements(); if (elems.length > 0) { final String contentType = elems[0].getName(); return contentType.equalsIgnoreCase(CONTENT_TYPE); } } return false; } /** * Adds all parameters within the Scanner to the list of parameters, as encoded by * encoding. For example, a scanner containing the string a=1&b=2&c=3 would add the * {@link NameValuePair NameValuePairs} a=1, b=2, and c=3 to the list of parameters. By convention, {@code '&'} and * {@code ';'} are accepted as parameter separators. * * @param parameters * List to add parameters to. * @param scanner * Input that contains the parameters to parse. * @param charset * Encoding to use when decoding the parameters. */ public static void parse( final List parameters, final Scanner scanner, final String charset) { parse(parameters, scanner, QP_SEP_PATTERN, charset); } /** * Adds all parameters within the Scanner to the list of * parameters, as encoded by encoding. For * example, a scanner containing the string a=1&b=2&c=3 would * add the {@link NameValuePair NameValuePairs} a=1, b=2, and c=3 to the * list of parameters. * * @param parameters * List to add parameters to. * @param scanner * Input that contains the parameters to parse. * @param parameterSepartorPattern * The Pattern string for parameter separators, by convention {@code "[&;]"} * @param charset * Encoding to use when decoding the parameters. */ public static void parse( final List parameters, final Scanner scanner, final String parameterSepartorPattern, final String charset) { scanner.useDelimiter(parameterSepartorPattern); while (scanner.hasNext()) { String name = null; String value = null; final String token = scanner.next(); final int i = token.indexOf(NAME_VALUE_SEPARATOR); if (i != -1) { name = decodeFormFields(token.substring(0, i).trim(), charset); value = decodeFormFields(token.substring(i + 1).trim(), charset); } else { name = decodeFormFields(token.trim(), charset); } parameters.add(new BasicNameValuePair(name, value)); } } /** * Query parameter separators. */ private static final char[] QP_SEPS = new char[] { QP_SEP_A, QP_SEP_S }; /** * Query parameter separator pattern. */ private static final String QP_SEP_PATTERN = "[" + new String(QP_SEPS) + "]"; /** * Returns a list of {@link NameValuePair NameValuePairs} as parsed from the given string using the given character * encoding. By convention, {@code '&'} and {@code ';'} are accepted as parameter separators. * * @param s * text to parse. * @param charset * Encoding to use when decoding the parameters. * @return a list of {@link NameValuePair} as built from the URI's query portion. * * @since 4.2 */ public static List parse(final String s, final Charset charset) { return parse(s, charset, QP_SEPS); } /** * Returns a list of {@link NameValuePair NameValuePairs} as parsed from the given string using the given character * encoding. * * @param s * text to parse. * @param charset * Encoding to use when decoding the parameters. * @param parameterSeparator * The characters used to separate parameters, by convention, {@code '&'} and {@code ';'}. * @return a list of {@link NameValuePair} as built from the URI's query portion. * * @since 4.3 */ public static List parse(final String s, final Charset charset, final char... parameterSeparator) { if (s == null) { return Collections.emptyList(); } final BasicHeaderValueParser parser = BasicHeaderValueParser.INSTANCE; final CharArrayBuffer buffer = new CharArrayBuffer(s.length()); buffer.append(s); final ParserCursor cursor = new ParserCursor(0, buffer.length()); final List list = new ArrayList(); while (!cursor.atEnd()) { final NameValuePair nvp = parser.parseNameValuePair(buffer, cursor, parameterSeparator); if (nvp.getName().length() > 0) { list.add(new BasicNameValuePair( decodeFormFields(nvp.getName(), charset), decodeFormFields(nvp.getValue(), charset))); } } return list; } /** * Returns a String that is suitable for use as an {@code application/x-www-form-urlencoded} * list of parameters in an HTTP PUT or HTTP POST. * * @param parameters The parameters to include. * @param charset The encoding to use. * @return An {@code application/x-www-form-urlencoded} string */ public static String format( final List parameters, final String charset) { return format(parameters, QP_SEP_A, charset); } /** * Returns a String that is suitable for use as an {@code application/x-www-form-urlencoded} * list of parameters in an HTTP PUT or HTTP POST. * * @param parameters The parameters to include. * @param parameterSeparator The parameter separator, by convention, {@code '&'} or {@code ';'}. * @param charset The encoding to use. * @return An {@code application/x-www-form-urlencoded} string * * @since 4.3 */ public static String format( final List parameters, final char parameterSeparator, final String charset) { final StringBuilder result = new StringBuilder(); for (final NameValuePair parameter : parameters) { final String encodedName = encodeFormFields(parameter.getName(), charset); final String encodedValue = encodeFormFields(parameter.getValue(), charset); if (result.length() > 0) { result.append(parameterSeparator); } result.append(encodedName); if (encodedValue != null) { result.append(NAME_VALUE_SEPARATOR); result.append(encodedValue); } } return result.toString(); } /** * Returns a String that is suitable for use as an {@code application/x-www-form-urlencoded} * list of parameters in an HTTP PUT or HTTP POST. * * @param parameters The parameters to include. * @param charset The encoding to use. * @return An {@code application/x-www-form-urlencoded} string * * @since 4.2 */ public static String format( final Iterable parameters, final Charset charset) { return format(parameters, QP_SEP_A, charset); } /** * Returns a String that is suitable for use as an {@code application/x-www-form-urlencoded} * list of parameters in an HTTP PUT or HTTP POST. * * @param parameters The parameters to include. * @param parameterSeparator The parameter separator, by convention, {@code '&'} or {@code ';'}. * @param charset The encoding to use. * @return An {@code application/x-www-form-urlencoded} string * * @since 4.3 */ public static String format( final Iterable parameters, final char parameterSeparator, final Charset charset) { final StringBuilder result = new StringBuilder(); for (final NameValuePair parameter : parameters) { final String encodedName = encodeFormFields(parameter.getName(), charset); final String encodedValue = encodeFormFields(parameter.getValue(), charset); if (result.length() > 0) { result.append(parameterSeparator); } result.append(encodedName); if (encodedValue != null) { result.append(NAME_VALUE_SEPARATOR); result.append(encodedValue); } } return result.toString(); } /** * Unreserved characters, i.e. alphanumeric, plus: {@code _ - ! . ~ ' ( ) *} *

* This list is the same as the {@code unreserved} list in * RFC 2396 */ private static final BitSet UNRESERVED = new BitSet(256); /** * Punctuation characters: , ; : $ & + = *

* These are the additional characters allowed by userinfo. */ private static final BitSet PUNCT = new BitSet(256); /** Characters which are safe to use in userinfo, * i.e. {@link #UNRESERVED} plus {@link #PUNCT}uation */ private static final BitSet USERINFO = new BitSet(256); /** Characters which are safe to use in a path, * i.e. {@link #UNRESERVED} plus {@link #PUNCT}uation plus / @ */ private static final BitSet PATHSAFE = new BitSet(256); /** Characters which are safe to use in a query or a fragment, * i.e. {@link #RESERVED} plus {@link #UNRESERVED} */ private static final BitSet URIC = new BitSet(256); /** * Reserved characters, i.e. {@code ;/?:@&=+$,[]} *

* This list is the same as the {@code reserved} list in * RFC 2396 * as augmented by * RFC 2732 */ private static final BitSet RESERVED = new BitSet(256); /** * Safe characters for x-www-form-urlencoded data, as per java.net.URLEncoder and browser behaviour, * i.e. alphanumeric plus {@code "-", "_", ".", "*"} */ private static final BitSet URLENCODER = new BitSet(256); static { // unreserved chars // alpha characters for (int i = 'a'; i <= 'z'; i++) { UNRESERVED.set(i); } for (int i = 'A'; i <= 'Z'; i++) { UNRESERVED.set(i); } // numeric characters for (int i = '0'; i <= '9'; i++) { UNRESERVED.set(i); } UNRESERVED.set('_'); // these are the charactes of the "mark" list UNRESERVED.set('-'); UNRESERVED.set('.'); UNRESERVED.set('*'); URLENCODER.or(UNRESERVED); // skip remaining unreserved characters UNRESERVED.set('!'); UNRESERVED.set('~'); UNRESERVED.set('\''); UNRESERVED.set('('); UNRESERVED.set(')'); // punct chars PUNCT.set(','); PUNCT.set(';'); PUNCT.set(':'); PUNCT.set('$'); PUNCT.set('&'); PUNCT.set('+'); PUNCT.set('='); // Safe for userinfo USERINFO.or(UNRESERVED); USERINFO.or(PUNCT); // URL path safe PATHSAFE.or(UNRESERVED); PATHSAFE.set('/'); // segment separator PATHSAFE.set(';'); // param separator PATHSAFE.set(':'); // rest as per list in 2396, i.e. : @ & = + $ , PATHSAFE.set('@'); PATHSAFE.set('&'); PATHSAFE.set('='); PATHSAFE.set('+'); PATHSAFE.set('$'); PATHSAFE.set(','); RESERVED.set(';'); RESERVED.set('/'); RESERVED.set('?'); RESERVED.set(':'); RESERVED.set('@'); RESERVED.set('&'); RESERVED.set('='); RESERVED.set('+'); RESERVED.set('$'); RESERVED.set(','); RESERVED.set('['); // added by RFC 2732 RESERVED.set(']'); // added by RFC 2732 URIC.or(RESERVED); URIC.or(UNRESERVED); } private static final int RADIX = 16; private static String urlEncode( final String content, final Charset charset, final BitSet safechars, final boolean blankAsPlus) { if (content == null) { return null; } final StringBuilder buf = new StringBuilder(); final ByteBuffer bb = charset.encode(content); while (bb.hasRemaining()) { final int b = bb.get() & 0xff; if (safechars.get(b)) { buf.append((char) b); } else if (blankAsPlus && b == ' ') { buf.append('+'); } else { buf.append("%"); final char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, RADIX)); final char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, RADIX)); buf.append(hex1); buf.append(hex2); } } return buf.toString(); } /** * Decode/unescape a portion of a URL, to use with the query part ensure {@code plusAsBlank} is true. * * @param content the portion to decode * @param charset the charset to use * @param plusAsBlank if {@code true}, then convert '+' to space (e.g. for www-url-form-encoded content), otherwise leave as is. * @return encoded string */ private static String urlDecode( final String content, final Charset charset, final boolean plusAsBlank) { if (content == null) { return null; } final ByteBuffer bb = ByteBuffer.allocate(content.length()); final CharBuffer cb = CharBuffer.wrap(content); while (cb.hasRemaining()) { final char c = cb.get(); if (c == '%' && cb.remaining() >= 2) { final char uc = cb.get(); final char lc = cb.get(); final int u = Character.digit(uc, 16); final int l = Character.digit(lc, 16); if (u != -1 && l != -1) { bb.put((byte) ((u << 4) + l)); } else { bb.put((byte) '%'); bb.put((byte) uc); bb.put((byte) lc); } } else if (plusAsBlank && c == '+') { bb.put((byte) ' '); } else { bb.put((byte) c); } } bb.flip(); return charset.decode(bb).toString(); } /** * Decode/unescape www-url-form-encoded content. * * @param content the content to decode, will decode '+' as space * @param charset the charset to use * @return encoded string */ private static String decodeFormFields (final String content, final String charset) { if (content == null) { return null; } return urlDecode(content, charset != null ? Charset.forName(charset) : Consts.UTF_8, true); } /** * Decode/unescape www-url-form-encoded content. * * @param content the content to decode, will decode '+' as space * @param charset the charset to use * @return encoded string */ private static String decodeFormFields (final String content, final Charset charset) { if (content == null) { return null; } return urlDecode(content, charset != null ? charset : Consts.UTF_8, true); } /** * Encode/escape www-url-form-encoded content. *

* Uses the {@link #URLENCODER} set of characters, rather than * the {@link #UNRSERVED} set; this is for compatibilty with previous * releases, URLEncoder.encode() and most browsers. * * @param content the content to encode, will convert space to '+' * @param charset the charset to use * @return encoded string */ private static String encodeFormFields(final String content, final String charset) { if (content == null) { return null; } return urlEncode(content, charset != null ? Charset.forName(charset) : Consts.UTF_8, URLENCODER, true); } /** * Encode/escape www-url-form-encoded content. *

* Uses the {@link #URLENCODER} set of characters, rather than * the {@link #UNRSERVED} set; this is for compatibilty with previous * releases, URLEncoder.encode() and most browsers. * * @param content the content to encode, will convert space to '+' * @param charset the charset to use * @return encoded string */ private static String encodeFormFields (final String content, final Charset charset) { if (content == null) { return null; } return urlEncode(content, charset != null ? charset : Consts.UTF_8, URLENCODER, true); } /** * Encode a String using the {@link #USERINFO} set of characters. *

* Used by URIBuilder to encode the userinfo segment. * * @param content the string to encode, does not convert space to '+' * @param charset the charset to use * @return the encoded string */ static String encUserInfo(final String content, final Charset charset) { return urlEncode(content, charset, USERINFO, false); } /** * Encode a String using the {@link #URIC} set of characters. *

* Used by URIBuilder to encode the query and fragment segments. * * @param content the string to encode, does not convert space to '+' * @param charset the charset to use * @return the encoded string */ static String encUric(final String content, final Charset charset) { return urlEncode(content, charset, URIC, false); } /** * Encode a String using the {@link #PATHSAFE} set of characters. *

* Used by URIBuilder to encode path segments. * * @param content the string to encode, does not convert space to '+' * @param charset the charset to use * @return the encoded string */ static String encPath(final String content, final Charset charset) { return urlEncode(content, charset, PATHSAFE, false); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/0040755 0000000 0000000 00000000000 12301751673 025357 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000147 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ClientConnectionManager.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ClientConnectionManager.ja0100644 0000000 0000000 00000010542 12301751673 032423 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.util.concurrent.TimeUnit; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.scheme.SchemeRegistry; /** * Management interface for {@link ManagedClientConnection client connections}. * The purpose of an HTTP connection manager is to serve as a factory for new * HTTP connections, manage persistent connections and synchronize access to * persistent connections making sure that only one thread of execution can * have access to a connection at a time. *

* Implementations of this interface must be thread-safe. Access to shared * data must be synchronized as methods of this interface may be executed * from multiple threads. * * @since 4.0 * * @deprecated (4.3) replaced by {@link HttpClientConnectionManager}. */ @Deprecated public interface ClientConnectionManager { /** * Obtains the scheme registry used by this manager. * * @return the scheme registry, never null */ SchemeRegistry getSchemeRegistry(); /** * Returns a new {@link ClientConnectionRequest}, from which a * {@link ManagedClientConnection} can be obtained or the request can be * aborted. */ ClientConnectionRequest requestConnection(HttpRoute route, Object state); /** * Releases a connection for use by others. * You may optionally specify how long the connection is valid * to be reused. Values <= 0 are considered to be valid forever. * If the connection is not marked as reusable, the connection will * not be reused regardless of the valid duration. * * If the connection has been released before, * the call will be ignored. * * @param conn the connection to release * @param validDuration the duration of time this connection is valid for reuse * @param timeUnit the unit of time validDuration is measured in * * @see #closeExpiredConnections() */ void releaseConnection(ManagedClientConnection conn, long validDuration, TimeUnit timeUnit); /** * Closes idle connections in the pool. * Open connections in the pool that have not been used for the * timespan given by the argument will be closed. * Currently allocated connections are not subject to this method. * Times will be checked with milliseconds precision * * All expired connections will also be closed. * * @param idletime the idle time of connections to be closed * @param tunit the unit for the idletime * * @see #closeExpiredConnections() */ void closeIdleConnections(long idletime, TimeUnit tunit); /** * Closes all expired connections in the pool. * Open connections in the pool that have not been used for * the timespan defined when the connection was released will be closed. * Currently allocated connections are not subject to this method. * Times will be checked with milliseconds precision. */ void closeExpiredConnections(); /** * Shuts down this connection manager and releases allocated resources. * This includes closing all connections, whether they are currently * used or not. */ void shutdown(); } ././@LongLink0100644 0000000 0000000 00000000147 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ClientConnectionRequest.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ClientConnectionRequest.ja0100644 0000000 0000000 00000005277 12301751667 032515 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.util.concurrent.TimeUnit; /** * Encapsulates a request for a {@link ManagedClientConnection}. * * @since 4.0 * * @deprecated (4.3) replaced by {@link ConnectionRequest}. */ @Deprecated public interface ClientConnectionRequest { /** * Obtains a connection within a given time. * This method will block until a connection becomes available, * the timeout expires, or the connection manager is * {@link ClientConnectionManager#shutdown() shut down}. * Timeouts are handled with millisecond precision. * * If {@link #abortRequest()} is called while this is blocking or * before this began, an {@link InterruptedException} will * be thrown. * * @param timeout the timeout, 0 or negative for no timeout * @param tunit the unit for the timeout, * may be null only if there is no timeout * * @return a connection that can be used to communicate * along the given route * * @throws ConnectionPoolTimeoutException * in case of a timeout * @throws InterruptedException * if the calling thread is interrupted while waiting */ ManagedClientConnection getConnection(long timeout, TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException; /** * Aborts the call to {@link #getConnection(long, TimeUnit)}, * causing it to throw an {@link InterruptedException}. */ void abortRequest(); } ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ConnectionKeepAliveStrategy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ConnectionKeepAliveStrateg0100644 0000000 0000000 00000005167 12301751670 032524 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import org.apache.http.HttpResponse; import org.apache.http.protocol.HttpContext; /** * Interface for deciding how long a connection can remain * idle before being reused. *

* Implementations of this interface must be thread-safe. Access to shared * data must be synchronized as methods of this interface may be executed * from multiple threads. * * @since 4.0 */ public interface ConnectionKeepAliveStrategy { /** * Returns the duration of time which this connection can be safely kept * idle. If the connection is left idle for longer than this period of time, * it MUST not reused. A value of 0 or less may be returned to indicate that * there is no suitable suggestion. * * When coupled with a {@link org.apache.http.ConnectionReuseStrategy}, if * {@link org.apache.http.ConnectionReuseStrategy#keepAlive( * HttpResponse, HttpContext)} returns true, this allows you to control * how long the reuse will last. If keepAlive returns false, this should * have no meaningful impact * * @param response * The last response received over the connection. * @param context * the context in which the connection is being used. * * @return the duration in ms for which it is safe to keep the connection * idle, or <=0 if no suggested duration. */ long getKeepAliveDuration(HttpResponse response, HttpContext context); } ././@LongLink0100644 0000000 0000000 00000000156 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ConnectionPoolTimeoutException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ConnectionPoolTimeoutExcep0100644 0000000 0000000 00000003637 12301751671 032573 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import org.apache.http.annotation.Immutable; /** * A timeout while waiting for an available connection * from a connection manager. * * * @since 4.0 */ @Immutable public class ConnectionPoolTimeoutException extends ConnectTimeoutException { private static final long serialVersionUID = -7898874842020245128L; /** * Creates a ConnectTimeoutException with a null detail message. */ public ConnectionPoolTimeoutException() { super(); } /** * Creates a ConnectTimeoutException with the specified detail message. * * @param message The exception detail message */ public ConnectionPoolTimeoutException(final String message) { super(message); } } ././@LongLink0100644 0000000 0000000 00000000150 12302131604 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ConnectionReleaseTrigger.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ConnectionReleaseTrigger.j0100644 0000000 0000000 00000005207 12301751673 032457 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; /** * Interface for releasing a connection. This can be implemented by various * "trigger" objects which are associated with a connection, for example * a {@link EofSensorInputStream stream} or an {@link BasicManagedEntity entity} * or the {@link ManagedClientConnection connection} itself. *

* The methods in this interface can safely be called multiple times. * The first invocation releases the connection, subsequent calls * are ignored. * * @since 4.0 */ public interface ConnectionReleaseTrigger { /** * Releases the connection with the option of keep-alive. This is a * "graceful" release and may cause IO operations for consuming the * remainder of a response entity. Use * {@link #abortConnection abortConnection} for a hard release. The * connection may be reused as specified by the duration. * * @throws IOException * in case of an IO problem. The connection will be released * anyway. */ void releaseConnection() throws IOException; /** * Releases the connection without the option of keep-alive. * This is a "hard" release that implies a shutdown of the connection. * Use {@link #releaseConnection()} for a graceful release. * * @throws IOException in case of an IO problem. * The connection will be released anyway. */ void abortConnection() throws IOException; } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ConnectionRequest.java0100644 0000000 0000000 00000005150 12301751670 031665 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import org.apache.http.HttpClientConnection; import org.apache.http.concurrent.Cancellable; /** * Represents a request for a {@link HttpClientConnection} whose life cycle * is managed by a connection manager. * * @since 4.3 */ public interface ConnectionRequest extends Cancellable { /** * Obtains a connection within a given time. * This method will block until a connection becomes available, * the timeout expires, or the connection manager is shut down. * Timeouts are handled with millisecond precision. * * If {@link #cancel()} is called while this is blocking or * before this began, an {@link InterruptedException} will * be thrown. * * @param timeout the timeout, 0 or negative for no timeout * @param tunit the unit for the timeout, * may be null only if there is no timeout * * @return a connection that can be used to communicate * along the given route * * @throws ConnectionPoolTimeoutException * in case of a timeout * @throws InterruptedException * if the calling thread is interrupted while waiting */ HttpClientConnection get(long timeout, TimeUnit tunit) throws InterruptedException, ExecutionException, ConnectionPoolTimeoutException; } ././@LongLink0100644 0000000 0000000 00000000147 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ConnectTimeoutException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ConnectTimeoutException.ja0100644 0000000 0000000 00000005623 12301751671 032513 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; import java.io.InterruptedIOException; import java.net.InetAddress; import java.util.Arrays; import org.apache.http.HttpHost; import org.apache.http.annotation.Immutable; /** * A timeout while connecting to an HTTP server or waiting for an * available connection from an HttpConnectionManager. * * * @since 4.0 */ @Immutable public class ConnectTimeoutException extends InterruptedIOException { private static final long serialVersionUID = -4816682903149535989L; private final HttpHost host; /** * Creates a ConnectTimeoutException with a null detail message. */ public ConnectTimeoutException() { super(); this.host = null; } /** * Creates a ConnectTimeoutException with the specified detail message. */ public ConnectTimeoutException(final String message) { super(message); this.host = null; } /** * Creates a ConnectTimeoutException based on original {@link IOException}. * * @since 4.3 */ public ConnectTimeoutException( final IOException cause, final HttpHost host, final InetAddress... remoteAddresses) { super("Connect to " + (host != null ? host.toHostString() : "remote host") + (remoteAddresses != null && remoteAddresses.length > 0 ? " " + Arrays.asList(remoteAddresses) : "") + ((cause != null && cause.getMessage() != null) ? " failed: " + cause.getMessage() : " timed out")); this.host = host; initCause(cause); } /** * @since 4.3 */ public HttpHost getHost() { return host; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/DnsResolver.java0100644 0000000 0000000 00000003701 12301751667 030471 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.net.InetAddress; import java.net.UnknownHostException; /** * Users may implement this interface to override the normal DNS lookup offered * by the OS. * * @since 4.2 */ public interface DnsResolver { /** * Returns the IP address for the specified host name, or null if the given * host is not recognized or the associated IP address cannot be used to * build an InetAddress instance. * * @see InetAddress * * @param host * The host name to be resolved by this resolver. * @return The IP address associated to the given host name, or null if the * host name is not known by the implementation class. */ InetAddress[] resolve(String host) throws UnknownHostException; } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/EofSensorInputStream.java0100644 0000000 0000000 00000022165 12301751673 032324 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; import java.io.InputStream; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.util.Args; /** * A stream wrapper that triggers actions on {@link #close close()} and EOF. * Primarily used to auto-release an underlying managed connection when the response * body is consumed or no longer needed. * * @see EofSensorWatcher * * @since 4.0 */ // don't use FilterInputStream as the base class, we'd have to // override markSupported(), mark(), and reset() to disable them @NotThreadSafe public class EofSensorInputStream extends InputStream implements ConnectionReleaseTrigger { /** * The wrapped input stream, while accessible. * The value changes to null when the wrapped stream * becomes inaccessible. */ protected InputStream wrappedStream; /** * Indicates whether this stream itself is closed. * If it isn't, but {@link #wrappedStream wrappedStream} * is null, we're running in EOF mode. * All read operations will indicate EOF without accessing * the underlying stream. After closing this stream, read * operations will trigger an {@link IOException IOException}. * * @see #isReadAllowed isReadAllowed */ private boolean selfClosed; /** The watcher to be notified, if any. */ private final EofSensorWatcher eofWatcher; /** * Creates a new EOF sensor. * If no watcher is passed, the underlying stream will simply be * closed when EOF is detected or {@link #close close} is called. * Otherwise, the watcher decides whether the underlying stream * should be closed before detaching from it. * * @param in the wrapped stream * @param watcher the watcher for events, or null for * auto-close behavior without notification */ public EofSensorInputStream(final InputStream in, final EofSensorWatcher watcher) { Args.notNull(in, "Wrapped stream"); wrappedStream = in; selfClosed = false; eofWatcher = watcher; } boolean isSelfClosed() { return selfClosed; } InputStream getWrappedStream() { return wrappedStream; } /** * Checks whether the underlying stream can be read from. * * @return true if the underlying stream is accessible, * false if this stream is in EOF mode and * detached from the underlying stream * * @throws IOException if this stream is already closed */ protected boolean isReadAllowed() throws IOException { if (selfClosed) { throw new IOException("Attempted read on closed stream."); } return (wrappedStream != null); } @Override public int read() throws IOException { int l = -1; if (isReadAllowed()) { try { l = wrappedStream.read(); checkEOF(l); } catch (final IOException ex) { checkAbort(); throw ex; } } return l; } @Override public int read(final byte[] b, final int off, final int len) throws IOException { int l = -1; if (isReadAllowed()) { try { l = wrappedStream.read(b, off, len); checkEOF(l); } catch (final IOException ex) { checkAbort(); throw ex; } } return l; } @Override public int read(final byte[] b) throws IOException { return read(b, 0, b.length); } @Override public int available() throws IOException { int a = 0; // not -1 if (isReadAllowed()) { try { a = wrappedStream.available(); // no checkEOF() here, available() can't trigger EOF } catch (final IOException ex) { checkAbort(); throw ex; } } return a; } @Override public void close() throws IOException { // tolerate multiple calls to close() selfClosed = true; checkClose(); } /** * Detects EOF and notifies the watcher. * This method should only be called while the underlying stream is * still accessible. Use {@link #isReadAllowed isReadAllowed} to * check that condition. *
* If EOF is detected, the watcher will be notified and this stream * is detached from the underlying stream. This prevents multiple * notifications from this stream. * * @param eof the result of the calling read operation. * A negative value indicates that EOF is reached. * * @throws IOException * in case of an IO problem on closing the underlying stream */ protected void checkEOF(final int eof) throws IOException { if ((wrappedStream != null) && (eof < 0)) { try { boolean scws = true; // should close wrapped stream? if (eofWatcher != null) { scws = eofWatcher.eofDetected(wrappedStream); } if (scws) { wrappedStream.close(); } } finally { wrappedStream = null; } } } /** * Detects stream close and notifies the watcher. * There's not much to detect since this is called by {@link #close close}. * The watcher will only be notified if this stream is closed * for the first time and before EOF has been detected. * This stream will be detached from the underlying stream to prevent * multiple notifications to the watcher. * * @throws IOException * in case of an IO problem on closing the underlying stream */ protected void checkClose() throws IOException { if (wrappedStream != null) { try { boolean scws = true; // should close wrapped stream? if (eofWatcher != null) { scws = eofWatcher.streamClosed(wrappedStream); } if (scws) { wrappedStream.close(); } } finally { wrappedStream = null; } } } /** * Detects stream abort and notifies the watcher. * There's not much to detect since this is called by * {@link #abortConnection abortConnection}. * The watcher will only be notified if this stream is aborted * for the first time and before EOF has been detected or the * stream has been {@link #close closed} gracefully. * This stream will be detached from the underlying stream to prevent * multiple notifications to the watcher. * * @throws IOException * in case of an IO problem on closing the underlying stream */ protected void checkAbort() throws IOException { if (wrappedStream != null) { try { boolean scws = true; // should close wrapped stream? if (eofWatcher != null) { scws = eofWatcher.streamAbort(wrappedStream); } if (scws) { wrappedStream.close(); } } finally { wrappedStream = null; } } } /** * Same as {@link #close close()}. */ public void releaseConnection() throws IOException { close(); } /** * Aborts this stream. * This is a special version of {@link #close close()} which prevents * re-use of the underlying connection, if any. Calling this method * indicates that there should be no attempt to read until the end of * the stream. */ public void abortConnection() throws IOException { // tolerate multiple calls selfClosed = true; checkAbort(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/EofSensorWatcher.java0100644 0000000 0000000 00000007316 12301751672 031446 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; import java.io.InputStream; /** * A watcher for {@link EofSensorInputStream}. Each stream will notify its * watcher at most once. * * @since 4.0 */ public interface EofSensorWatcher { /** * Indicates that EOF is detected. * * @param wrapped the underlying stream which has reached EOF * * @return true if wrapped should be closed, * false if it should be left alone * * @throws IOException * in case of an IO problem, for example if the watcher itself * closes the underlying stream. The caller will leave the * wrapped stream alone, as if false was returned. */ boolean eofDetected(InputStream wrapped) throws IOException; /** * Indicates that the {@link EofSensorInputStream stream} is closed. * This method will be called only if EOF was not detected * before closing. Otherwise, {@link #eofDetected eofDetected} is called. * * @param wrapped the underlying stream which has not reached EOF * * @return true if wrapped should be closed, * false if it should be left alone * * @throws IOException * in case of an IO problem, for example if the watcher itself * closes the underlying stream. The caller will leave the * wrapped stream alone, as if false was returned. */ boolean streamClosed(InputStream wrapped) throws IOException; /** * Indicates that the {@link EofSensorInputStream stream} is aborted. * This method will be called only if EOF was not detected * before aborting. Otherwise, {@link #eofDetected eofDetected} is called. *

* This method will also be invoked when an input operation causes an * IOException to be thrown to make sure the input stream gets shut down. * * @param wrapped the underlying stream which has not reached EOF * * @return true if wrapped should be closed, * false if it should be left alone * * @throws IOException * in case of an IO problem, for example if the watcher itself * closes the underlying stream. The caller will leave the * wrapped stream alone, as if false was returned. */ boolean streamAbort(InputStream wrapped) throws IOException; } ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/HttpClientConnectionManager.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/HttpClientConnectionManage0100644 0000000 0000000 00000015505 12301751673 032514 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; import java.util.concurrent.TimeUnit; import org.apache.http.HttpClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.protocol.HttpContext; /** * Represents a manager of persistent client connections. *

* The purpose of an HTTP connection manager is to serve as a factory for new * HTTP connections, manage persistent connections and synchronize access to * persistent connections making sure that only one thread of execution can * have access to a connection at a time. *

* Implementations of this interface must be thread-safe. Access to shared * data must be synchronized as methods of this interface may be executed * from multiple threads. * * @since 4.3 */ public interface HttpClientConnectionManager { /** * Returns a new {@link ConnectionRequest}, from which a * {@link HttpClientConnection} can be obtained or the request can be * aborted. *

* Please note that newly allocated connections can be returned * in the closed state. The consumer of that connection is responsible * for fully establishing the route the to the connection target * by calling {@link #connect(org.apache.http.HttpClientConnection, * org.apache.http.conn.routing.HttpRoute, int, * org.apache.http.protocol.HttpContext) connect} in order to connect * directly to the target or to the first proxy hop, optionally calling * {@link #upgrade(org.apache.http.HttpClientConnection, * org.apache.http.conn.routing.HttpRoute, * org.apache.http.protocol.HttpContext) upgrade} method to upgrade * the connection after having executed CONNECT method to * all intermediate proxy hops and and finally calling {@link #routeComplete( * org.apache.http.HttpClientConnection, * org.apache.http.conn.routing.HttpRoute, * org.apache.http.protocol.HttpContext) routeComplete} to mark the route * as fully completed. * * @param route HTTP route of the requested connection. * @param state expected state of the connection or null * if the connection is not expected to carry any state. */ ConnectionRequest requestConnection(HttpRoute route, Object state); /** * Releases the connection back to the manager making it potentially * re-usable by other consumers. Optionally, the maximum period * of how long the manager should keep the connection alive can be * defined using validDuration and timeUnit * parameters. * * @param conn the managed connection to release. * @param validDuration the duration of time this connection is valid for reuse. * @param timeUnit the time unit. * * @see #closeExpiredConnections() */ void releaseConnection( HttpClientConnection conn, Object newState, long validDuration, TimeUnit timeUnit); /** * Connects the underlying connection socket to the connection target in case * of a direct route or to the first proxy hop in case of a route via a proxy * (or multiple proxies). * * @param conn the managed connection. * @param route the route of the connection. * @param connectTimeout connect timeout in milliseconds. * @param context the actual HTTP context. * @throws IOException */ void connect( HttpClientConnection conn, HttpRoute route, int connectTimeout, HttpContext context) throws IOException; /** * Upgrades the underlying connection socket to TLS/SSL (or another layering * protocol) after having executed CONNECT method to all * intermediate proxy hops * * @param conn the managed connection. * @param route the route of the connection. * @param context the actual HTTP context. * @throws IOException */ void upgrade( HttpClientConnection conn, HttpRoute route, HttpContext context) throws IOException; /** * Marks the connection as fully established with all its intermediate * hops completed. * * @param conn the managed connection. * @param route the route of the connection. * @param context the actual HTTP context. * @throws IOException */ void routeComplete( HttpClientConnection conn, HttpRoute route, HttpContext context) throws IOException; /** * Closes idle connections in the pool. *

* Open connections in the pool that have not been used for the * timespan given by the argument will be closed. * Currently allocated connections are not subject to this method. * Times will be checked with milliseconds precision * * All expired connections will also be closed. * * @param idletime the idle time of connections to be closed * @param tunit the unit for the idletime * * @see #closeExpiredConnections() */ void closeIdleConnections(long idletime, TimeUnit tunit); /** * Closes all expired connections in the pool. *

* Open connections in the pool that have not been used for * the timespan defined when the connection was released will be closed. * Currently allocated connections are not subject to this method. * Times will be checked with milliseconds precision. */ void closeExpiredConnections(); /** * Shuts down this connection manager and releases allocated resources. * This includes closing all connections, whether they are currently * used or not. */ void shutdown(); } ././@LongLink0100644 0000000 0000000 00000000145 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/HttpConnectionFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/HttpConnectionFactory.java0100644 0000000 0000000 00000002725 12301751673 032514 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import org.apache.http.HttpConnection; import org.apache.http.config.ConnectionConfig; /** * Generic {@link HttpConnection} factory. * * @since 4.3 */ public interface HttpConnectionFactory { C create(T route, ConnectionConfig config); } ././@LongLink0100644 0000000 0000000 00000000150 12302131604 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/HttpHostConnectException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/HttpHostConnectException.j0100644 0000000 0000000 00000005404 12301751667 032503 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; import java.net.ConnectException; import java.net.InetAddress; import java.util.Arrays; import org.apache.http.HttpHost; import org.apache.http.annotation.Immutable; /** * A {@link ConnectException} that specifies the {@link HttpHost} that was * being connected to. * * @since 4.0 */ @Immutable public class HttpHostConnectException extends ConnectException { private static final long serialVersionUID = -3194482710275220224L; private final HttpHost host; /** * @deprecated (4.3) use {@link #HttpHostConnectException(java.io.IOException, org.apache.http.HttpHost, * java.net.InetAddress...)} */ @Deprecated public HttpHostConnectException(final HttpHost host, final ConnectException cause) { this(cause, host, null); } /** * Creates a HttpHostConnectException based on original {@link java.io.IOException}. * * @since 4.3 */ public HttpHostConnectException( final IOException cause, final HttpHost host, final InetAddress... remoteAddresses) { super("Connect to " + (host != null ? host.toHostString() : "remote host") + (remoteAddresses != null && remoteAddresses .length > 0 ? " " + Arrays.asList(remoteAddresses) : "") + ((cause != null && cause.getMessage() != null) ? " failed: " + cause.getMessage() : " refused")); this.host = host; initCause(cause); } public HttpHost getHost() { return this.host; } } ././@LongLink0100644 0000000 0000000 00000000145 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/HttpInetSocketAddress.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/HttpInetSocketAddress.java0100644 0000000 0000000 00000004142 12301751671 032434 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.net.InetAddress; import java.net.InetSocketAddress; import org.apache.http.HttpHost; import org.apache.http.util.Args; /** * Extended {@link InetSocketAddress} implementation that also provides access to the original * {@link HttpHost} used to resolve the address. * * @since 4.2 no longer used. * * @deprecated (4.3) */ @Deprecated public class HttpInetSocketAddress extends InetSocketAddress { private static final long serialVersionUID = -6650701828361907957L; private final HttpHost httphost; public HttpInetSocketAddress(final HttpHost httphost, final InetAddress addr, final int port) { super(addr, port); Args.notNull(httphost, "HTTP host"); this.httphost = httphost; } public HttpHost getHttpHost() { return this.httphost; } @Override public String toString() { return this.httphost.getHostName() + ":" + getPort(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/HttpRoutedConnection.java0100644 0000000 0000000 00000005634 12301751672 032350 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import javax.net.ssl.SSLSession; import org.apache.http.HttpInetConnection; import org.apache.http.conn.routing.HttpRoute; /** * Interface to access routing information of a client side connection. * * @since 4.1 * * @deprecated (4.3) replaced by {@link HttpClientConnectionManager}. */ @Deprecated public interface HttpRoutedConnection extends HttpInetConnection { /** * Indicates whether this connection is secure. * The return value is well-defined only while the connection is open. * It may change even while the connection is open. * * @return true if this connection is secure, * false otherwise */ boolean isSecure(); /** * Obtains the current route of this connection. * * @return the route established so far, or * null if not connected */ HttpRoute getRoute(); /** * Obtains the SSL session of the underlying connection, if any. * If this connection is open, and the underlying socket is an * {@link javax.net.ssl.SSLSocket SSLSocket}, the SSL session of * that socket is obtained. This is a potentially blocking operation. *
* Note: Whether the underlying socket is an SSL socket * can not necessarily be determined via {@link #isSecure}. * Plain sockets may be considered secure, for example if they are * connected to a known host in the same network segment. * On the other hand, SSL sockets may be considered insecure, * for example depending on the chosen cipher suite. * * @return the underlying SSL session if available, * null otherwise */ SSLSession getSSLSession(); } ././@LongLink0100644 0000000 0000000 00000000147 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ManagedClientConnection.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ManagedClientConnection.ja0100644 0000000 0000000 00000022217 12301751671 032405 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLSession; import org.apache.http.HttpClientConnection; import org.apache.http.HttpHost; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; /** * A client-side connection with advanced connection logic. * Instances are typically obtained from a connection manager. * * @since 4.0 * * @deprecated (4.3) replaced by {@link HttpClientConnectionManager}. */ @Deprecated public interface ManagedClientConnection extends HttpClientConnection, HttpRoutedConnection, ManagedHttpClientConnection, ConnectionReleaseTrigger { /** * Indicates whether this connection is secure. * The return value is well-defined only while the connection is open. * It may change even while the connection is open. * * @return true if this connection is secure, * false otherwise */ boolean isSecure(); /** * Obtains the current route of this connection. * * @return the route established so far, or * null if not connected */ HttpRoute getRoute(); /** * Obtains the SSL session of the underlying connection, if any. * If this connection is open, and the underlying socket is an * {@link javax.net.ssl.SSLSocket SSLSocket}, the SSL session of * that socket is obtained. This is a potentially blocking operation. *
* Note: Whether the underlying socket is an SSL socket * can not necessarily be determined via {@link #isSecure}. * Plain sockets may be considered secure, for example if they are * connected to a known host in the same network segment. * On the other hand, SSL sockets may be considered insecure, * for example depending on the chosen cipher suite. * * @return the underlying SSL session if available, * null otherwise */ SSLSession getSSLSession(); /** * Opens this connection according to the given route. * * @param route the route along which to open. It will be opened to * the first proxy if present, or directly to the target. * @param context the context for opening this connection * @param params the parameters for opening this connection * * @throws IOException in case of a problem */ void open(HttpRoute route, HttpContext context, HttpParams params) throws IOException; /** * Indicates that a tunnel to the target has been established. * The route is the one previously passed to {@link #open open}. * Subsequently, {@link #layerProtocol layerProtocol} can be called * to layer the TLS/SSL protocol on top of the tunnelled connection. *
* Note: In HttpClient 3, a call to the corresponding method * would automatically trigger the layering of the TLS/SSL protocol. * This is not the case anymore, you can establish a tunnel without * layering a new protocol over the connection. * * @param secure true if the tunnel should be considered * secure, false otherwise * @param params the parameters for tunnelling this connection * * @throws IOException in case of a problem */ void tunnelTarget(boolean secure, HttpParams params) throws IOException; /** * Indicates that a tunnel to an intermediate proxy has been established. * This is used exclusively for so-called proxy chains, where * a request has to pass through multiple proxies before reaching the * target. In that case, all proxies but the last need to be tunnelled * when establishing the connection. Tunnelling of the last proxy to the * target is optional and would be indicated via {@link #tunnelTarget}. * * @param next the proxy to which the tunnel was established. * This is not the proxy through which * the tunnel was established, but the new end point * of the tunnel. The tunnel does not yet * reach to the target, use {@link #tunnelTarget} * to indicate an end-to-end tunnel. * @param secure true if the connection should be * considered secure, false otherwise * @param params the parameters for tunnelling this connection * * @throws IOException in case of a problem */ void tunnelProxy(HttpHost next, boolean secure, HttpParams params) throws IOException; /** * Layers a new protocol on top of a {@link #tunnelTarget tunnelled} * connection. This is typically used to create a TLS/SSL connection * through a proxy. * The route is the one previously passed to {@link #open open}. * It is not guaranteed that the layered connection is * {@link #isSecure secure}. * * @param context the context for layering on top of this connection * @param params the parameters for layering on top of this connection * * @throws IOException in case of a problem */ void layerProtocol(HttpContext context, HttpParams params) throws IOException; /** * Marks this connection as being in a reusable communication state. * The checkpoints for reuseable communication states (in the absence * of pipelining) are before sending a request and after receiving * the response in its entirety. * The connection will automatically clear the checkpoint when * used for communication. A call to this method indicates that * the next checkpoint has been reached. *
* A reusable communication state is necessary but not sufficient * for the connection to be reused. * A {@link #getRoute route} mismatch, the connection being closed, * or other circumstances might prevent reuse. */ void markReusable(); /** * Marks this connection as not being in a reusable state. * This can be used immediately before releasing this connection * to prevent its reuse. Reasons for preventing reuse include * error conditions and the evaluation of a * {@link org.apache.http.ConnectionReuseStrategy reuse strategy}. *
* Note: * It is not necessary to call here before writing to * or reading from this connection. Communication attempts will * automatically unmark the state as non-reusable. It can then * be switched back using {@link #markReusable markReusable}. */ void unmarkReusable(); /** * Indicates whether this connection is in a reusable communication state. * See {@link #markReusable markReusable} and * {@link #unmarkReusable unmarkReusable} for details. * * @return true if this connection is marked as being in * a reusable communication state, * false otherwise */ boolean isMarkedReusable(); /** * Assigns a state object to this connection. Connection managers may make * use of the connection state when allocating persistent connections. * * @param state The state object */ void setState(Object state); /** * Returns the state object associated with this connection. * * @return The state object */ Object getState(); /** * Sets the duration that this connection can remain idle before it is * reused. The connection should not be used again if this time elapses. The * idle duration must be reset after each request sent over this connection. * The elapsed time starts counting when the connection is released, which * is typically after the headers (and any response body, if present) is * fully consumed. */ void setIdleDuration(long duration, TimeUnit unit); } ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ManagedHttpClientConnection.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ManagedHttpClientConnectio0100644 0000000 0000000 00000005313 12301751671 032474 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; import java.net.Socket; import javax.net.ssl.SSLSession; import org.apache.http.HttpClientConnection; import org.apache.http.HttpInetConnection; /** * Represents a managed connection whose state and life cycle is managed by * a connection manager. This interface extends {@link HttpClientConnection} * with methods to bind the connection to an arbitrary socket and * to obtain SSL session details. * * @since 4.3 */ public interface ManagedHttpClientConnection extends HttpClientConnection, HttpInetConnection { /** * Returns connection ID which is expected to be unique * for the life span of the connection manager. */ String getId(); /** * Binds this connection to the given socket. The connection * is considered open if it is bound and the underlying socket * is connection to a remote host. * * @param socket the socket to bind the connection to. * @throws IOException */ void bind(Socket socket) throws IOException; /** * Returns the underlying socket. */ Socket getSocket(); /** * Obtains the SSL session of the underlying connection, if any. * If this connection is open, and the underlying socket is an * {@link javax.net.ssl.SSLSocket SSLSocket}, the SSL session of * that socket is obtained. This is a potentially blocking operation. * * @return the underlying SSL session if available, * null otherwise */ SSLSession getSSLSession(); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/package-info.java0100644 0000000 0000000 00000002355 12301751673 030550 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Client connection management APIs. */ package org.apache.http.conn; httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/SchemePortResolver.java0100644 0000000 0000000 00000002776 12301751673 032026 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import org.apache.http.HttpHost; /** * Strategy for default port resolution for protocol schemes. * * @since 4.3 */ public interface SchemePortResolver { /** * Returns the actual port for the host based on the protocol scheme. */ int resolve(HttpHost host) throws UnsupportedSchemeException; } ././@LongLink0100644 0000000 0000000 00000000152 12302131604 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/UnsupportedSchemeException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/UnsupportedSchemeException0100644 0000000 0000000 00000003301 12301751673 032630 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; import org.apache.http.annotation.Immutable; /** * Signals failure to establish connection using an unknown protocol scheme. * * @since 4.3 */ @Immutable public class UnsupportedSchemeException extends IOException { private static final long serialVersionUID = 3597127619218687636L; /** * Creates a UnsupportedSchemeException with the specified detail message. */ public UnsupportedSchemeException(final String message) { super(message); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/params/0040755 0000000 0000000 00000000000 12301751673 026642 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/params/ConnConnectionPNames.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/params/ConnConnectionPName0100644 0000000 0000000 00000004624 12301751673 032426 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.params; /** * Parameter names for HTTP client connections. * * @since 4.0 * * @deprecated (4.1) use custom {@link * org.apache.http.impl.conn.DefaultHttpResponseParser} implementation. */ @Deprecated public interface ConnConnectionPNames { /** * Defines the maximum number of ignorable lines before we expect * a HTTP response's status line. *

* With HTTP/1.1 persistent connections, the problem arises that * broken scripts could return a wrong Content-Length * (there are more bytes sent than specified). * Unfortunately, in some cases, this cannot be detected after the * bad response, but only before the next one. * So HttpClient must be able to skip those surplus lines this way. *

*

* This parameter expects a value of type {@link Integer}. * 0 disallows all garbage/empty lines before the status line. * Use {@link java.lang.Integer#MAX_VALUE} for unlimited number. *

* * @deprecated (4.1) Use custom {@link * org.apache.http.impl.conn.DefaultHttpResponseParser} implementation */ @Deprecated public static final String MAX_STATUS_LINE_GARBAGE = "http.connection.max-status-line-garbage"; } ././@LongLink0100644 0000000 0000000 00000000150 12302131604 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/params/ConnManagerPNames.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/params/ConnManagerPNames.j0100644 0000000 0000000 00000004765 12301751673 032322 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.params; /** * Parameter names for connection managers in HttpConn. * * @since 4.0 * * @deprecated (4.1) use configuration methods of the specific connection manager implementation. */ @Deprecated public interface ConnManagerPNames { /** * Defines the timeout in milliseconds used when retrieving an instance of * {@link org.apache.http.conn.ManagedClientConnection} from the * {@link org.apache.http.conn.ClientConnectionManager}. *

* This parameter expects a value of type {@link Long}. */ public static final String TIMEOUT = "http.conn-manager.timeout"; /** * Defines the maximum number of connections per route. * This limit is interpreted by client connection managers * and applies to individual manager instances. *

* This parameter expects a value of type {@link ConnPerRoute}. *

*/ public static final String MAX_CONNECTIONS_PER_ROUTE = "http.conn-manager.max-per-route"; /** * Defines the maximum number of connections in total. * This limit is interpreted by client connection managers * and applies to individual manager instances. *

* This parameter expects a value of type {@link Integer}. */ public static final String MAX_TOTAL_CONNECTIONS = "http.conn-manager.max-total"; } ././@LongLink0100644 0000000 0000000 00000000146 12302131604 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/params/ConnRoutePNames.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/params/ConnRoutePNames.jav0100644 0000000 0000000 00000005651 12301751673 032370 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.params; /** * Parameter names for connection routing. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.client.config.RequestConfig}. */ @Deprecated public interface ConnRoutePNames { /** * Parameter for the default proxy. * The default value will be used by some * {@link org.apache.http.conn.routing.HttpRoutePlanner HttpRoutePlanner} * implementations, in particular the default implementation. *

* This parameter expects a value of type {@link org.apache.http.HttpHost}. *

*/ public static final String DEFAULT_PROXY = "http.route.default-proxy"; /** * Parameter for the local address. * On machines with multiple network interfaces, this parameter * can be used to select the network interface from which the * connection originates. * It will be interpreted by the standard * {@link org.apache.http.conn.routing.HttpRoutePlanner HttpRoutePlanner} * implementations, in particular the default implementation. *

* This parameter expects a value of type {@link java.net.InetAddress}. *

*/ public static final String LOCAL_ADDRESS = "http.route.local-address"; /** * Parameter for an forced route. * The forced route will be interpreted by the standard * {@link org.apache.http.conn.routing.HttpRoutePlanner HttpRoutePlanner} * implementations. * Instead of computing a route, the given forced route will be * returned, even if it points to the wrong target host. *

* This parameter expects a value of type * {@link org.apache.http.conn.routing.HttpRoute HttpRoute}. *

*/ public static final String FORCED_ROUTE = "http.route.forced-route"; } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/params/package-info.java0100644 0000000 0000000 00000002363 12301751673 032032 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Deprecated. * @deprecated (4.3). */ package org.apache.http.conn.params; httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/routing/0040755 0000000 0000000 00000000000 12301751670 027043 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000152 12302131604 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/routing/BasicRouteDirector.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/routing/BasicRouteDirector0100644 0000000 0000000 00000013420 12301751667 032525 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.routing; import org.apache.http.annotation.Immutable; import org.apache.http.util.Args; /** * Basic {@link HttpRouteDirector} implementation. * * @since 4.0 */ @Immutable public class BasicRouteDirector implements HttpRouteDirector { /** * Provides the next step. * * @param plan the planned route * @param fact the currently established route, or * null if nothing is established * * @return one of the constants defined in this class, indicating * either the next step to perform, or success, or failure. * 0 is for success, a negative value for failure. */ public int nextStep(final RouteInfo plan, final RouteInfo fact) { Args.notNull(plan, "Planned route"); int step = UNREACHABLE; if ((fact == null) || (fact.getHopCount() < 1)) { step = firstStep(plan); } else if (plan.getHopCount() > 1) { step = proxiedStep(plan, fact); } else { step = directStep(plan, fact); } return step; } // nextStep /** * Determines the first step to establish a route. * * @param plan the planned route * * @return the first step */ protected int firstStep(final RouteInfo plan) { return (plan.getHopCount() > 1) ? CONNECT_PROXY : CONNECT_TARGET; } /** * Determines the next step to establish a direct connection. * * @param plan the planned route * @param fact the currently established route * * @return one of the constants defined in this class, indicating * either the next step to perform, or success, or failure */ protected int directStep(final RouteInfo plan, final RouteInfo fact) { if (fact.getHopCount() > 1) { return UNREACHABLE; } if (!plan.getTargetHost().equals(fact.getTargetHost())) { return UNREACHABLE; // If the security is too low, we could now suggest to layer // a secure protocol on the direct connection. Layering on direct // connections has not been supported in HttpClient 3.x, we don't // consider it here until there is a real-life use case for it. } // Should we tolerate if security is better than planned? // (plan.isSecure() && !fact.isSecure()) if (plan.isSecure() != fact.isSecure()) { return UNREACHABLE; } // Local address has to match only if the plan specifies one. if ((plan.getLocalAddress() != null) && !plan.getLocalAddress().equals(fact.getLocalAddress()) ) { return UNREACHABLE; } return COMPLETE; } /** * Determines the next step to establish a connection via proxy. * * @param plan the planned route * @param fact the currently established route * * @return one of the constants defined in this class, indicating * either the next step to perform, or success, or failure */ protected int proxiedStep(final RouteInfo plan, final RouteInfo fact) { if (fact.getHopCount() <= 1) { return UNREACHABLE; } if (!plan.getTargetHost().equals(fact.getTargetHost())) { return UNREACHABLE; } final int phc = plan.getHopCount(); final int fhc = fact.getHopCount(); if (phc < fhc) { return UNREACHABLE; } for (int i=0; i fhc) { return TUNNEL_PROXY; // need to extend the proxy chain } // proxy chain and target are the same, check tunnelling and layering if ((fact.isTunnelled() && !plan.isTunnelled()) || (fact.isLayered() && !plan.isLayered())) { return UNREACHABLE; } if (plan.isTunnelled() && !fact.isTunnelled()) { return TUNNEL_TARGET; } if (plan.isLayered() && !fact.isLayered()) { return LAYER_PROTOCOL; } // tunnel and layering are the same, remains to check the security // Should we tolerate if security is better than planned? // (plan.isSecure() && !fact.isSecure()) if (plan.isSecure() != fact.isSecure()) { return UNREACHABLE; } return COMPLETE; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/routing/HttpRoute.java0100644 0000000 0000000 00000026401 12301751670 031644 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.routing; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.apache.http.HttpHost; import org.apache.http.annotation.Immutable; import org.apache.http.util.Args; import org.apache.http.util.LangUtils; /** * The route for a request. * * @since 4.0 */ @Immutable public final class HttpRoute implements RouteInfo, Cloneable { /** The target host to connect to. */ private final HttpHost targetHost; /** * The local address to connect from. * null indicates that the default should be used. */ private final InetAddress localAddress; /** The proxy servers, if any. Never null. */ private final List proxyChain; /** Whether the the route is tunnelled through the proxy. */ private final TunnelType tunnelled; /** Whether the route is layered. */ private final LayerType layered; /** Whether the route is (supposed to be) secure. */ private final boolean secure; private HttpRoute(final HttpHost target, final InetAddress local, final List proxies, final boolean secure, final TunnelType tunnelled, final LayerType layered) { Args.notNull(target, "Target host"); this.targetHost = target; this.localAddress = local; if (proxies != null && !proxies.isEmpty()) { this.proxyChain = new ArrayList(proxies); } else { this.proxyChain = null; } if (tunnelled == TunnelType.TUNNELLED) { Args.check(this.proxyChain != null, "Proxy required if tunnelled"); } this.secure = secure; this.tunnelled = tunnelled != null ? tunnelled : TunnelType.PLAIN; this.layered = layered != null ? layered : LayerType.PLAIN; } /** * Creates a new route with all attributes specified explicitly. * * @param target the host to which to route * @param local the local address to route from, or * null for the default * @param proxies the proxy chain to use, or * null for a direct route * @param secure true if the route is (to be) secure, * false otherwise * @param tunnelled the tunnel type of this route * @param layered the layering type of this route */ public HttpRoute(final HttpHost target, final InetAddress local, final HttpHost[] proxies, final boolean secure, final TunnelType tunnelled, final LayerType layered) { this(target, local, proxies != null ? Arrays.asList(proxies) : null, secure, tunnelled, layered); } /** * Creates a new route with at most one proxy. * * @param target the host to which to route * @param local the local address to route from, or * null for the default * @param proxy the proxy to use, or * null for a direct route * @param secure true if the route is (to be) secure, * false otherwise * @param tunnelled true if the route is (to be) tunnelled * via the proxy, * false otherwise * @param layered true if the route includes a * layered protocol, * false otherwise */ public HttpRoute(final HttpHost target, final InetAddress local, final HttpHost proxy, final boolean secure, final TunnelType tunnelled, final LayerType layered) { this(target, local, proxy != null ? Collections.singletonList(proxy) : null, secure, tunnelled, layered); } /** * Creates a new direct route. * That is a route without a proxy. * * @param target the host to which to route * @param local the local address to route from, or * null for the default * @param secure true if the route is (to be) secure, * false otherwise */ public HttpRoute(final HttpHost target, final InetAddress local, final boolean secure) { this(target, local, Collections.emptyList(), secure, TunnelType.PLAIN, LayerType.PLAIN); } /** * Creates a new direct insecure route. * * @param target the host to which to route */ public HttpRoute(final HttpHost target) { this(target, null, Collections.emptyList(), false, TunnelType.PLAIN, LayerType.PLAIN); } /** * Creates a new route through a proxy. * When using this constructor, the proxy MUST be given. * For convenience, it is assumed that a secure connection will be * layered over a tunnel through the proxy. * * @param target the host to which to route * @param local the local address to route from, or * null for the default * @param proxy the proxy to use * @param secure true if the route is (to be) secure, * false otherwise */ public HttpRoute(final HttpHost target, final InetAddress local, final HttpHost proxy, final boolean secure) { this(target, local, Collections.singletonList(Args.notNull(proxy, "Proxy host")), secure, secure ? TunnelType.TUNNELLED : TunnelType.PLAIN, secure ? LayerType.LAYERED : LayerType.PLAIN); } /** * Creates a new plain route through a proxy. * * @param target the host to which to route * @param proxy the proxy to use * * @since 4.3 */ public HttpRoute(final HttpHost target, final HttpHost proxy) { this(target, null, proxy, false); } public final HttpHost getTargetHost() { return this.targetHost; } public final InetAddress getLocalAddress() { return this.localAddress; } public final InetSocketAddress getLocalSocketAddress() { return this.localAddress != null ? new InetSocketAddress(this.localAddress, 0) : null; } public final int getHopCount() { return proxyChain != null ? proxyChain.size() + 1 : 1; } public final HttpHost getHopTarget(final int hop) { Args.notNegative(hop, "Hop index"); final int hopcount = getHopCount(); Args.check(hop < hopcount, "Hop index exceeds tracked route length"); if (hop < hopcount - 1) { return this.proxyChain.get(hop); } else { return this.targetHost; } } public final HttpHost getProxyHost() { return proxyChain != null && !this.proxyChain.isEmpty() ? this.proxyChain.get(0) : null; } public final TunnelType getTunnelType() { return this.tunnelled; } public final boolean isTunnelled() { return (this.tunnelled == TunnelType.TUNNELLED); } public final LayerType getLayerType() { return this.layered; } public final boolean isLayered() { return (this.layered == LayerType.LAYERED); } public final boolean isSecure() { return this.secure; } /** * Compares this route to another. * * @param obj the object to compare with * * @return true if the argument is the same route, * false */ @Override public final boolean equals(final Object obj) { if (this == obj) { return true; } if (obj instanceof HttpRoute) { final HttpRoute that = (HttpRoute) obj; return // Do the cheapest tests first (this.secure == that.secure) && (this.tunnelled == that.tunnelled) && (this.layered == that.layered) && LangUtils.equals(this.targetHost, that.targetHost) && LangUtils.equals(this.localAddress, that.localAddress) && LangUtils.equals(this.proxyChain, that.proxyChain); } else { return false; } } /** * Generates a hash code for this route. * * @return the hash code */ @Override public final int hashCode() { int hash = LangUtils.HASH_SEED; hash = LangUtils.hashCode(hash, this.targetHost); hash = LangUtils.hashCode(hash, this.localAddress); if (this.proxyChain != null) { for (final HttpHost element : this.proxyChain) { hash = LangUtils.hashCode(hash, element); } } hash = LangUtils.hashCode(hash, this.secure); hash = LangUtils.hashCode(hash, this.tunnelled); hash = LangUtils.hashCode(hash, this.layered); return hash; } /** * Obtains a description of this route. * * @return a human-readable representation of this route */ @Override public final String toString() { final StringBuilder cab = new StringBuilder(50 + getHopCount()*30); if (this.localAddress != null) { cab.append(this.localAddress); cab.append("->"); } cab.append('{'); if (this.tunnelled == TunnelType.TUNNELLED) { cab.append('t'); } if (this.layered == LayerType.LAYERED) { cab.append('l'); } if (this.secure) { cab.append('s'); } cab.append("}->"); if (this.proxyChain != null) { for (final HttpHost aProxyChain : this.proxyChain) { cab.append(aProxyChain); cab.append("->"); } } cab.append(this.targetHost); return cab.toString(); } // default implementation of clone() is sufficient @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } } ././@LongLink0100644 0000000 0000000 00000000151 12302131604 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/routing/HttpRouteDirector.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/routing/HttpRouteDirector.0100644 0000000 0000000 00000005125 12301751667 032504 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.routing; /** * Provides directions on establishing a route. * Implementations of this interface compare a planned route with * a tracked route and indicate the next step required. * * @since 4.0 */ public interface HttpRouteDirector { /** Indicates that the route can not be established at all. */ public final static int UNREACHABLE = -1; /** Indicates that the route is complete. */ public final static int COMPLETE = 0; /** Step: open connection to target. */ public final static int CONNECT_TARGET = 1; /** Step: open connection to proxy. */ public final static int CONNECT_PROXY = 2; /** Step: tunnel through proxy to target. */ public final static int TUNNEL_TARGET = 3; /** Step: tunnel through proxy to other proxy. */ public final static int TUNNEL_PROXY = 4; /** Step: layer protocol (over tunnel). */ public final static int LAYER_PROTOCOL = 5; /** * Provides the next step. * * @param plan the planned route * @param fact the currently established route, or * null if nothing is established * * @return one of the constants defined in this interface, indicating * either the next step to perform, or success, or failure. * 0 is for success, a negative value for failure. */ public int nextStep(RouteInfo plan, RouteInfo fact); } ././@LongLink0100644 0000000 0000000 00000000150 12302131604 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/routing/HttpRoutePlanner.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/routing/HttpRoutePlanner.j0100644 0000000 0000000 00000005121 12301751670 032470 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.routing; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.protocol.HttpContext; /** * Encapsulates logic to compute a {@link HttpRoute} to a target host. * Implementations may for example be based on parameters, or on the * standard Java system properties. *

* Implementations of this interface must be thread-safe. Access to shared * data must be synchronized as methods of this interface may be executed * from multiple threads. * * @since 4.0 */ public interface HttpRoutePlanner { /** * Determines the route for a request. * * @param target the target host for the request. * Implementations may accept null * if they can still determine a route, for example * to a default target or by inspecting the request. * @param request the request to execute * @param context the context to use for the subsequent execution. * Implementations may accept null. * * @return the route that the request should take * * @throws HttpException in case of a problem */ public HttpRoute determineRoute(HttpHost target, HttpRequest request, HttpContext context) throws HttpException; } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/routing/package-info.java0100644 0000000 0000000 00000002362 12301751670 032232 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Client connection routing APIs. */ package org.apache.http.conn.routing; httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/routing/RouteInfo.java0100644 0000000 0000000 00000012016 12301751667 031623 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.routing; import java.net.InetAddress; import org.apache.http.HttpHost; /** * Read-only interface for route information. * * @since 4.0 */ public interface RouteInfo { /** * The tunnelling type of a route. * Plain routes are established by connecting to the target or * the first proxy. * Tunnelled routes are established by connecting to the first proxy * and tunnelling through all proxies to the target. * Routes without a proxy cannot be tunnelled. */ public enum TunnelType { PLAIN, TUNNELLED } /** * The layering type of a route. * Plain routes are established by connecting or tunnelling. * Layered routes are established by layering a protocol such as TLS/SSL * over an existing connection. * Protocols can only be layered over a tunnel to the target, or * or over a direct connection without proxies. *
* Layering a protocol * over a direct connection makes little sense, since the connection * could be established with the new protocol in the first place. * But we don't want to exclude that use case. */ public enum LayerType { PLAIN, LAYERED } /** * Obtains the target host. * * @return the target host */ HttpHost getTargetHost(); /** * Obtains the local address to connect from. * * @return the local address, * or null */ InetAddress getLocalAddress(); /** * Obtains the number of hops in this route. * A direct route has one hop. A route through a proxy has two hops. * A route through a chain of n proxies has n+1 hops. * * @return the number of hops in this route */ int getHopCount(); /** * Obtains the target of a hop in this route. * The target of the last hop is the {@link #getTargetHost target host}, * the target of previous hops is the respective proxy in the chain. * For a route through exactly one proxy, target of hop 0 is the proxy * and target of hop 1 is the target host. * * @param hop index of the hop for which to get the target, * 0 for first * * @return the target of the given hop * * @throws IllegalArgumentException * if the argument is negative or not less than * {@link #getHopCount getHopCount()} */ HttpHost getHopTarget(int hop); /** * Obtains the first proxy host. * * @return the first proxy in the proxy chain, or * null if this route is direct */ HttpHost getProxyHost(); /** * Obtains the tunnel type of this route. * If there is a proxy chain, only end-to-end tunnels are considered. * * @return the tunnelling type */ TunnelType getTunnelType(); /** * Checks whether this route is tunnelled through a proxy. * If there is a proxy chain, only end-to-end tunnels are considered. * * @return true if tunnelled end-to-end through at least * one proxy, * false otherwise */ boolean isTunnelled(); /** * Obtains the layering type of this route. * In the presence of proxies, only layering over an end-to-end tunnel * is considered. * * @return the layering type */ LayerType getLayerType(); /** * Checks whether this route includes a layered protocol. * In the presence of proxies, only layering over an end-to-end tunnel * is considered. * * @return true if layered, * false otherwise */ boolean isLayered(); /** * Checks whether this route is secure. * * @return true if secure, * false otherwise */ boolean isSecure(); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/routing/RouteTracker.java0100644 0000000 0000000 00000026724 12301751667 032336 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.routing; import java.net.InetAddress; import org.apache.http.HttpHost; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.util.Args; import org.apache.http.util.Asserts; import org.apache.http.util.LangUtils; /** * Helps tracking the steps in establishing a route. * * @since 4.0 */ @NotThreadSafe public final class RouteTracker implements RouteInfo, Cloneable { /** The target host to connect to. */ private final HttpHost targetHost; /** * The local address to connect from. * null indicates that the default should be used. */ private final InetAddress localAddress; // the attributes above are fixed at construction time // now follow attributes that indicate the established route /** Whether the first hop of the route is established. */ private boolean connected; /** The proxy chain, if any. */ private HttpHost[] proxyChain; /** Whether the the route is tunnelled end-to-end through proxies. */ private TunnelType tunnelled; /** Whether the route is layered over a tunnel. */ private LayerType layered; /** Whether the route is secure. */ private boolean secure; /** * Creates a new route tracker. * The target and origin need to be specified at creation time. * * @param target the host to which to route * @param local the local address to route from, or * null for the default */ public RouteTracker(final HttpHost target, final InetAddress local) { Args.notNull(target, "Target host"); this.targetHost = target; this.localAddress = local; this.tunnelled = TunnelType.PLAIN; this.layered = LayerType.PLAIN; } /** * @since 4.2 */ public void reset() { this.connected = false; this.proxyChain = null; this.tunnelled = TunnelType.PLAIN; this.layered = LayerType.PLAIN; this.secure = false; } /** * Creates a new tracker for the given route. * Only target and origin are taken from the route, * everything else remains to be tracked. * * @param route the route to track */ public RouteTracker(final HttpRoute route) { this(route.getTargetHost(), route.getLocalAddress()); } /** * Tracks connecting to the target. * * @param secure true if the route is secure, * false otherwise */ public final void connectTarget(final boolean secure) { Asserts.check(!this.connected, "Already connected"); this.connected = true; this.secure = secure; } /** * Tracks connecting to the first proxy. * * @param proxy the proxy connected to * @param secure true if the route is secure, * false otherwise */ public final void connectProxy(final HttpHost proxy, final boolean secure) { Args.notNull(proxy, "Proxy host"); Asserts.check(!this.connected, "Already connected"); this.connected = true; this.proxyChain = new HttpHost[]{ proxy }; this.secure = secure; } /** * Tracks tunnelling to the target. * * @param secure true if the route is secure, * false otherwise */ public final void tunnelTarget(final boolean secure) { Asserts.check(this.connected, "No tunnel unless connected"); Asserts.notNull(this.proxyChain, "No tunnel without proxy"); this.tunnelled = TunnelType.TUNNELLED; this.secure = secure; } /** * Tracks tunnelling to a proxy in a proxy chain. * This will extend the tracked proxy chain, but it does not mark * the route as tunnelled. Only end-to-end tunnels are considered there. * * @param proxy the proxy tunnelled to * @param secure true if the route is secure, * false otherwise */ public final void tunnelProxy(final HttpHost proxy, final boolean secure) { Args.notNull(proxy, "Proxy host"); Asserts.check(this.connected, "No tunnel unless connected"); Asserts.notNull(this.proxyChain, "No tunnel without proxy"); // prepare an extended proxy chain final HttpHost[] proxies = new HttpHost[this.proxyChain.length+1]; System.arraycopy(this.proxyChain, 0, proxies, 0, this.proxyChain.length); proxies[proxies.length-1] = proxy; this.proxyChain = proxies; this.secure = secure; } /** * Tracks layering a protocol. * * @param secure true if the route is secure, * false otherwise */ public final void layerProtocol(final boolean secure) { // it is possible to layer a protocol over a direct connection, // although this case is probably not considered elsewhere Asserts.check(this.connected, "No layered protocol unless connected"); this.layered = LayerType.LAYERED; this.secure = secure; } public final HttpHost getTargetHost() { return this.targetHost; } public final InetAddress getLocalAddress() { return this.localAddress; } public final int getHopCount() { int hops = 0; if (this.connected) { if (proxyChain == null) { hops = 1; } else { hops = proxyChain.length + 1; } } return hops; } public final HttpHost getHopTarget(final int hop) { Args.notNegative(hop, "Hop index"); final int hopcount = getHopCount(); Args.check(hop < hopcount, "Hop index exceeds tracked route length"); HttpHost result = null; if (hop < hopcount-1) { result = this.proxyChain[hop]; } else { result = this.targetHost; } return result; } public final HttpHost getProxyHost() { return (this.proxyChain == null) ? null : this.proxyChain[0]; } public final boolean isConnected() { return this.connected; } public final TunnelType getTunnelType() { return this.tunnelled; } public final boolean isTunnelled() { return (this.tunnelled == TunnelType.TUNNELLED); } public final LayerType getLayerType() { return this.layered; } public final boolean isLayered() { return (this.layered == LayerType.LAYERED); } public final boolean isSecure() { return this.secure; } /** * Obtains the tracked route. * If a route has been tracked, it is {@link #isConnected connected}. * If not connected, nothing has been tracked so far. * * @return the tracked route, or * null if nothing has been tracked so far */ public final HttpRoute toRoute() { return !this.connected ? null : new HttpRoute(this.targetHost, this.localAddress, this.proxyChain, this.secure, this.tunnelled, this.layered); } /** * Compares this tracked route to another. * * @param o the object to compare with * * @return true if the argument is the same tracked route, * false */ @Override public final boolean equals(final Object o) { if (o == this) { return true; } if (!(o instanceof RouteTracker)) { return false; } final RouteTracker that = (RouteTracker) o; return // Do the cheapest checks first (this.connected == that.connected) && (this.secure == that.secure) && (this.tunnelled == that.tunnelled) && (this.layered == that.layered) && LangUtils.equals(this.targetHost, that.targetHost) && LangUtils.equals(this.localAddress, that.localAddress) && LangUtils.equals(this.proxyChain, that.proxyChain); } /** * Generates a hash code for this tracked route. * Route trackers are modifiable and should therefore not be used * as lookup keys. Use {@link #toRoute toRoute} to obtain an * unmodifiable representation of the tracked route. * * @return the hash code */ @Override public final int hashCode() { int hash = LangUtils.HASH_SEED; hash = LangUtils.hashCode(hash, this.targetHost); hash = LangUtils.hashCode(hash, this.localAddress); if (this.proxyChain != null) { for (final HttpHost element : this.proxyChain) { hash = LangUtils.hashCode(hash, element); } } hash = LangUtils.hashCode(hash, this.connected); hash = LangUtils.hashCode(hash, this.secure); hash = LangUtils.hashCode(hash, this.tunnelled); hash = LangUtils.hashCode(hash, this.layered); return hash; } /** * Obtains a description of the tracked route. * * @return a human-readable representation of the tracked route */ @Override public final String toString() { final StringBuilder cab = new StringBuilder(50 + getHopCount()*30); cab.append("RouteTracker["); if (this.localAddress != null) { cab.append(this.localAddress); cab.append("->"); } cab.append('{'); if (this.connected) { cab.append('c'); } if (this.tunnelled == TunnelType.TUNNELLED) { cab.append('t'); } if (this.layered == LayerType.LAYERED) { cab.append('l'); } if (this.secure) { cab.append('s'); } cab.append("}->"); if (this.proxyChain != null) { for (final HttpHost element : this.proxyChain) { cab.append(element); cab.append("->"); } } cab.append(this.targetHost); cab.append(']'); return cab.toString(); } // default implementation of clone() is sufficient @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/0040755 0000000 0000000 00000000000 12301751672 026622 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000161 12302131604 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSchemeSocketFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSchemeSocket0100644 0000000 0000000 00000004571 12301751672 032434 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.scheme; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; /** * Extended {@link SchemeSocketFactory} interface for layered sockets such as SSL/TLS. * * @since 4.1 * * @deprecated (4.2) use {@link SchemeLayeredSocketFactory} */ @Deprecated public interface LayeredSchemeSocketFactory extends SchemeSocketFactory { /** * Returns a socket connected to the given host that is layered over an * existing socket. Used primarily for creating secure sockets through * proxies. * * @param socket the existing socket * @param target the name of the target host. * @param port the port to connect to on the target host * @param autoClose a flag for closing the underling socket when the created * socket is closed * * @return Socket a new socket * * @throws IOException if an I/O error occurs while creating the socket * @throws UnknownHostException if the IP address of the host cannot be * determined */ Socket createLayeredSocket( Socket socket, String target, int port, boolean autoClose ) throws IOException, UnknownHostException; } ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSocketFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSocketFactor0100644 0000000 0000000 00000004553 12301751672 032446 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.scheme; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; /** * A {@link SocketFactory SocketFactory} for layered sockets (SSL/TLS). * See there for things to consider when implementing a socket factory. * * @since 4.0 * * @deprecated (4.1) use {@link SchemeSocketFactory} */ @Deprecated public interface LayeredSocketFactory extends SocketFactory { /** * Returns a socket connected to the given host that is layered over an * existing socket. Used primarily for creating secure sockets through * proxies. * * @param socket the existing socket * @param host the host name/IP * @param port the port on the host * @param autoClose a flag for closing the underling socket when the created * socket is closed * * @return Socket a new socket * * @throws IOException if an I/O error occurs while creating the socket * @throws UnknownHostException if the IP address of the host cannot be * determined */ Socket createSocket( Socket socket, String host, int port, boolean autoClose ) throws IOException, UnknownHostException; } ././@LongLink0100644 0000000 0000000 00000000162 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSocketFactoryAdaptor.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/LayeredSocketFactor0100644 0000000 0000000 00000003607 12301751672 032445 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.scheme; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; /** * @deprecated (4.1) do not use */ @Deprecated class LayeredSocketFactoryAdaptor extends SocketFactoryAdaptor implements LayeredSocketFactory { private final LayeredSchemeSocketFactory factory; LayeredSocketFactoryAdaptor(final LayeredSchemeSocketFactory factory) { super(factory); this.factory = factory; } public Socket createSocket( final Socket socket, final String host, final int port, final boolean autoClose) throws IOException, UnknownHostException { return this.factory.createLayeredSocket(socket, host, port, autoClose); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/package-info.java0100644 0000000 0000000 00000002363 12301751672 032012 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Deprecated. * @deprecated (4.3). */ package org.apache.http.conn.scheme; httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/Scheme.java0100644 0000000 0000000 00000021260 12301751672 030667 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.scheme; import java.util.Locale; import org.apache.http.annotation.Immutable; import org.apache.http.util.Args; import org.apache.http.util.LangUtils; /** * Encapsulates specifics of a protocol scheme such as "http" or "https". Schemes are identified * by lowercase names. Supported schemes are typically collected in a {@link SchemeRegistry * SchemeRegistry}. *

* For example, to configure support for "https://" URLs, you could write code like the following: *

 * Scheme https = new Scheme("https", 443, new MySecureSocketFactory());
 * SchemeRegistry registry = new SchemeRegistry();
 * registry.register(https);
 * 
* * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.conn.SchemePortResolver} for default port * resolution and {@link org.apache.http.config.Registry} for socket factory lookups. */ @Immutable @Deprecated public final class Scheme { /** The name of this scheme, in lowercase. (e.g. http, https) */ private final String name; /** The socket factory for this scheme */ private final SchemeSocketFactory socketFactory; /** The default port for this scheme */ private final int defaultPort; /** Indicates whether this scheme allows for layered connections */ private final boolean layered; /** A string representation, for {@link #toString toString}. */ private String stringRep; /* * This is used to cache the result of the toString() method * Since the method always generates the same value, there's no * need to synchronize, and it does not affect immutability. */ /** * Creates a new scheme. * Whether the created scheme allows for layered connections * depends on the class of factory. * * @param name the scheme name, for example "http". * The name will be converted to lowercase. * @param port the default port for this scheme * @param factory the factory for creating sockets for communication * with this scheme * * @since 4.1 */ public Scheme(final String name, final int port, final SchemeSocketFactory factory) { Args.notNull(name, "Scheme name"); Args.check(port > 0 && port <= 0xffff, "Port is invalid"); Args.notNull(factory, "Socket factory"); this.name = name.toLowerCase(Locale.ENGLISH); this.defaultPort = port; if (factory instanceof SchemeLayeredSocketFactory) { this.layered = true; this.socketFactory = factory; } else if (factory instanceof LayeredSchemeSocketFactory) { this.layered = true; this.socketFactory = new SchemeLayeredSocketFactoryAdaptor2((LayeredSchemeSocketFactory) factory); } else { this.layered = false; this.socketFactory = factory; } } /** * Creates a new scheme. * Whether the created scheme allows for layered connections * depends on the class of factory. * * @param name the scheme name, for example "http". * The name will be converted to lowercase. * @param factory the factory for creating sockets for communication * with this scheme * @param port the default port for this scheme * * @deprecated (4.1) Use {@link #Scheme(String, int, SchemeSocketFactory)} */ @Deprecated public Scheme(final String name, final SocketFactory factory, final int port) { Args.notNull(name, "Scheme name"); Args.notNull(factory, "Socket factory"); Args.check(port > 0 && port <= 0xffff, "Port is invalid"); this.name = name.toLowerCase(Locale.ENGLISH); if (factory instanceof LayeredSocketFactory) { this.socketFactory = new SchemeLayeredSocketFactoryAdaptor( (LayeredSocketFactory) factory); this.layered = true; } else { this.socketFactory = new SchemeSocketFactoryAdaptor(factory); this.layered = false; } this.defaultPort = port; } /** * Obtains the default port. * * @return the default port for this scheme */ public final int getDefaultPort() { return defaultPort; } /** * Obtains the socket factory. * If this scheme is {@link #isLayered layered}, the factory implements * {@link LayeredSocketFactory LayeredSocketFactory}. * * @return the socket factory for this scheme * * @deprecated (4.1) Use {@link #getSchemeSocketFactory()} */ @Deprecated public final SocketFactory getSocketFactory() { if (this.socketFactory instanceof SchemeSocketFactoryAdaptor) { return ((SchemeSocketFactoryAdaptor) this.socketFactory).getFactory(); } else { if (this.layered) { return new LayeredSocketFactoryAdaptor( (LayeredSchemeSocketFactory) this.socketFactory); } else { return new SocketFactoryAdaptor(this.socketFactory); } } } /** * Obtains the socket factory. * If this scheme is {@link #isLayered layered}, the factory implements * {@link LayeredSocketFactory LayeredSchemeSocketFactory}. * * @return the socket factory for this scheme * * @since 4.1 */ public final SchemeSocketFactory getSchemeSocketFactory() { return this.socketFactory; } /** * Obtains the scheme name. * * @return the name of this scheme, in lowercase */ public final String getName() { return name; } /** * Indicates whether this scheme allows for layered connections. * * @return true if layered connections are possible, * false otherwise */ public final boolean isLayered() { return layered; } /** * Resolves the correct port for this scheme. * Returns the given port if it is valid, the default port otherwise. * * @param port the port to be resolved, * a negative number to obtain the default port * * @return the given port or the defaultPort */ public final int resolvePort(final int port) { return port <= 0 ? defaultPort : port; } /** * Return a string representation of this object. * * @return a human-readable string description of this scheme */ @Override public final String toString() { if (stringRep == null) { final StringBuilder buffer = new StringBuilder(); buffer.append(this.name); buffer.append(':'); buffer.append(Integer.toString(this.defaultPort)); stringRep = buffer.toString(); } return stringRep; } @Override public final boolean equals(final Object obj) { if (this == obj) { return true; } if (obj instanceof Scheme) { final Scheme that = (Scheme) obj; return this.name.equals(that.name) && this.defaultPort == that.defaultPort && this.layered == that.layered; } else { return false; } } @Override public int hashCode() { int hash = LangUtils.HASH_SEED; hash = LangUtils.hashCode(hash, this.defaultPort); hash = LangUtils.hashCode(hash, this.name); hash = LangUtils.hashCode(hash, this.layered); return hash; } } ././@LongLink0100644 0000000 0000000 00000000161 12302131604 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeLayeredSocketFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeLayeredSocket0100644 0000000 0000000 00000004602 12301751672 032427 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.scheme; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import org.apache.http.params.HttpParams; /** * Extended {@link SchemeSocketFactory} interface for layered sockets such as SSL/TLS. * * @since 4.2 * * @deprecated (4.3) use {@link * org.apache.http.conn.socket.LayeredConnectionSocketFactory} */ @Deprecated public interface SchemeLayeredSocketFactory extends SchemeSocketFactory { /** * Returns a socket connected to the given host that is layered over an * existing socket. Used primarily for creating secure sockets through * proxies. * * @param socket the existing socket * @param target the name of the target host. * @param port the port to connect to on the target host * @param params HTTP parameters * * @return Socket a new socket * * @throws IOException if an I/O error occurs while creating the socket * @throws UnknownHostException if the IP address of the host cannot be * determined */ Socket createLayeredSocket( Socket socket, String target, int port, HttpParams params) throws IOException, UnknownHostException; } ././@LongLink0100644 0000000 0000000 00000000170 12302131604 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeLayeredSocketFactoryAdaptor.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeLayeredSocket0100644 0000000 0000000 00000003715 12301751672 032433 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.scheme; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import org.apache.http.params.HttpParams; /** * @deprecated (4.2) do not use */ @Deprecated class SchemeLayeredSocketFactoryAdaptor extends SchemeSocketFactoryAdaptor implements SchemeLayeredSocketFactory { private final LayeredSocketFactory factory; SchemeLayeredSocketFactoryAdaptor(final LayeredSocketFactory factory) { super(factory); this.factory = factory; } public Socket createLayeredSocket( final Socket socket, final String target, final int port, final HttpParams params) throws IOException, UnknownHostException { return this.factory.createSocket(socket, target, port, true); } } ././@LongLink0100644 0000000 0000000 00000000171 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeLayeredSocketFactoryAdaptor2.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeLayeredSocket0100644 0000000 0000000 00000005201 12301751672 032423 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.scheme; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.params.HttpParams; /** * @deprecated (4.2) do not use */ @Deprecated class SchemeLayeredSocketFactoryAdaptor2 implements SchemeLayeredSocketFactory { private final LayeredSchemeSocketFactory factory; SchemeLayeredSocketFactoryAdaptor2(final LayeredSchemeSocketFactory factory) { super(); this.factory = factory; } public Socket createSocket(final HttpParams params) throws IOException { return this.factory.createSocket(params); } public Socket connectSocket( final Socket sock, final InetSocketAddress remoteAddress, final InetSocketAddress localAddress, final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { return this.factory.connectSocket(sock, remoteAddress, localAddress, params); } public boolean isSecure(final Socket sock) throws IllegalArgumentException { return this.factory.isSecure(sock); } public Socket createLayeredSocket( final Socket socket, final String target, final int port, final HttpParams params) throws IOException, UnknownHostException { return this.factory.createLayeredSocket(socket, target, port, true); } } ././@LongLink0100644 0000000 0000000 00000000145 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeRegistry.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeRegistry.java0100644 0000000 0000000 00000012375 12301751672 032427 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.scheme; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.http.HttpHost; import org.apache.http.annotation.ThreadSafe; import org.apache.http.util.Args; /** * A set of supported protocol {@link Scheme}s. * Schemes are identified by lowercase names. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.config.Registry} */ @ThreadSafe @Deprecated public final class SchemeRegistry { /** The available schemes in this registry. */ private final ConcurrentHashMap registeredSchemes; /** * Creates a new, empty scheme registry. */ public SchemeRegistry() { super(); registeredSchemes = new ConcurrentHashMap(); } /** * Obtains a scheme by name. * * @param name the name of the scheme to look up (in lowercase) * * @return the scheme, never null * * @throws IllegalStateException * if the scheme with the given name is not registered */ public final Scheme getScheme(final String name) { final Scheme found = get(name); if (found == null) { throw new IllegalStateException ("Scheme '"+name+"' not registered."); } return found; } /** * Obtains the scheme for a host. * Convenience method for getScheme(host.getSchemeName()) * * @param host the host for which to obtain the scheme * * @return the scheme for the given host, never null * * @throws IllegalStateException * if a scheme with the respective name is not registered */ public final Scheme getScheme(final HttpHost host) { Args.notNull(host, "Host"); return getScheme(host.getSchemeName()); } /** * Obtains a scheme by name, if registered. * * @param name the name of the scheme to look up (in lowercase) * * @return the scheme, or * null if there is none by this name */ public final Scheme get(final String name) { Args.notNull(name, "Scheme name"); // leave it to the caller to use the correct name - all lowercase //name = name.toLowerCase(); final Scheme found = registeredSchemes.get(name); return found; } /** * Registers a scheme. * The scheme can later be retrieved by its name * using {@link #getScheme(String) getScheme} or {@link #get get}. * * @param sch the scheme to register * * @return the scheme previously registered with that name, or * null if none was registered */ public final Scheme register(final Scheme sch) { Args.notNull(sch, "Scheme"); final Scheme old = registeredSchemes.put(sch.getName(), sch); return old; } /** * Unregisters a scheme. * * @param name the name of the scheme to unregister (in lowercase) * * @return the unregistered scheme, or * null if there was none */ public final Scheme unregister(final String name) { Args.notNull(name, "Scheme name"); // leave it to the caller to use the correct name - all lowercase //name = name.toLowerCase(); final Scheme gone = registeredSchemes.remove(name); return gone; } /** * Obtains the names of the registered schemes. * * @return List containing registered scheme names. */ public final List getSchemeNames() { return new ArrayList(registeredSchemes.keySet()); } /** * Populates the internal collection of registered {@link Scheme protocol schemes} * with the content of the map passed as a parameter. * * @param map protocol schemes */ public void setItems(final Map map) { if (map == null) { return; } registeredSchemes.clear(); registeredSchemes.putAll(map); } } ././@LongLink0100644 0000000 0000000 00000000152 12302131604 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeSocketFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeSocketFactory0100644 0000000 0000000 00000013547 12301751672 032461 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.scheme; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.params.HttpParams; /** * A factory for creating, initializing and connecting sockets. The factory encapsulates the logic * for establishing a socket connection. * * @since 4.1 * * @deprecated (4.3) use {@link org.apache.http.conn.socket.ConnectionSocketFactory} */ @Deprecated public interface SchemeSocketFactory { /** * Creates a new, unconnected socket. The socket should subsequently be passed to * {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams)}. * * @param params Optional {@link HttpParams parameters}. In most cases these parameters * will not be required and will have no effect, as usually socket * initialization should take place in the * {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams)} * method. However, in rare cases one may want to pass additional parameters * to this method in order to create a customized {@link Socket} instance, * for instance bound to a SOCKS proxy server. * * @return a new socket * * @throws IOException if an I/O error occurs while creating the socket */ Socket createSocket(HttpParams params) throws IOException; /** * Connects a socket to the target host with the given remote address. *

* Please note that {@link org.apache.http.conn.HttpInetSocketAddress} class should * be used in order to pass the target remote address along with the original * {@link org.apache.http.HttpHost} value used to resolve the address. The use of * {@link org.apache.http.conn.HttpInetSocketAddress} can also ensure that no reverse * DNS lookup will be performed if the target remote address was specified * as an IP address. * * @param sock the socket to connect, as obtained from * {@link #createSocket(HttpParams) createSocket}. * null indicates that a new socket * should be created and connected. * @param remoteAddress the remote address to connect to. * @param localAddress the local address to bind the socket to, or * null for any * @param params additional {@link HttpParams parameters} for connecting * * @return the connected socket. The returned object may be different * from the sock argument if this factory supports * a layered protocol. * * @throws IOException if an I/O error occurs * @throws UnknownHostException if the IP address of the target host * can not be determined * @throws ConnectTimeoutException if the socket cannot be connected * within the time limit defined in the params * * @see org.apache.http.conn.HttpInetSocketAddress */ Socket connectSocket( Socket sock, InetSocketAddress remoteAddress, InetSocketAddress localAddress, HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException; /** * Checks whether a socket provides a secure connection. The socket must be * {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams) connected} * by this factory. The factory will not perform I/O operations in this method. *

* As a rule of thumb, plain sockets are not secure and TLS/SSL sockets are secure. However, * there may be application specific deviations. For example, a plain socket to a host in the * same intranet ("trusted zone") could be considered secure. On the other hand, a TLS/SSL * socket could be considered insecure based on the cipher suite chosen for the connection. * * @param sock the connected socket to check * * @return true if the connection of the socket * should be considered secure, or * false if it should not * * @throws IllegalArgumentException * if the argument is invalid, for example because it is * not a connected socket or was created by a different * socket factory. * Note that socket factories are not required to * check these conditions, they may simply return a default * value when called with an invalid socket argument. */ boolean isSecure(Socket sock) throws IllegalArgumentException; } ././@LongLink0100644 0000000 0000000 00000000161 12302131604 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeSocketFactoryAdaptor.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SchemeSocketFactory0100644 0000000 0000000 00000006271 12301751672 032455 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.scheme; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.params.HttpParams; /** * @deprecated (4.1) do not use */ @Deprecated class SchemeSocketFactoryAdaptor implements SchemeSocketFactory { private final SocketFactory factory; SchemeSocketFactoryAdaptor(final SocketFactory factory) { super(); this.factory = factory; } public Socket connectSocket( final Socket sock, final InetSocketAddress remoteAddress, final InetSocketAddress localAddress, final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { final String host = remoteAddress.getHostName(); final int port = remoteAddress.getPort(); InetAddress local = null; int localPort = 0; if (localAddress != null) { local = localAddress.getAddress(); localPort = localAddress.getPort(); } return this.factory.connectSocket(sock, host, port, local, localPort, params); } public Socket createSocket(final HttpParams params) throws IOException { return this.factory.createSocket(); } public boolean isSecure(final Socket sock) throws IllegalArgumentException { return this.factory.isSecure(sock); } public SocketFactory getFactory() { return this.factory; } @Override public boolean equals(final Object obj) { if (obj == null) { return false; } if (this == obj) { return true; } if (obj instanceof SchemeSocketFactoryAdaptor) { return this.factory.equals(((SchemeSocketFactoryAdaptor)obj).factory); } else { return this.factory.equals(obj); } } @Override public int hashCode() { return this.factory.hashCode(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SocketFactory.java0100644 0000000 0000000 00000011413 12301751672 032242 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.scheme; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.params.HttpParams; /** * A factory for creating, initializing and connecting sockets. * The factory encapsulates the logic for establishing a socket connection. * * @since 4.0 * * @deprecated (4.1) use {@link SchemeSocketFactory} */ @Deprecated public interface SocketFactory { /** * Creates a new, unconnected socket. * The socket should subsequently be passed to * {@link #connectSocket connectSocket}. * * @return a new socket * * @throws IOException if an I/O error occurs while creating the socket */ Socket createSocket() throws IOException; /** * Connects a socket to the given host. * * @param sock the socket to connect, as obtained from * {@link #createSocket createSocket}. * null indicates that a new socket * should be created and connected. * @param host the host to connect to * @param port the port to connect to on the host * @param localAddress the local address to bind the socket to, or * null for any * @param localPort the port on the local machine, * 0 or a negative number for any * @param params additional {@link HttpParams parameters} for connecting * * @return the connected socket. The returned object may be different * from the sock argument if this factory supports * a layered protocol. * * @throws IOException if an I/O error occurs * @throws UnknownHostException if the IP address of the target host * can not be determined * @throws ConnectTimeoutException if the socket cannot be connected * within the time limit defined in the params */ Socket connectSocket( Socket sock, String host, int port, InetAddress localAddress, int localPort, HttpParams params ) throws IOException, UnknownHostException, ConnectTimeoutException; /** * Checks whether a socket provides a secure connection. * The socket must be {@link #connectSocket connected} * by this factory. * The factory will not perform I/O operations * in this method. *
* As a rule of thumb, plain sockets are not secure and * TLS/SSL sockets are secure. However, there may be * application specific deviations. For example, a plain * socket to a host in the same intranet ("trusted zone") * could be considered secure. On the other hand, a * TLS/SSL socket could be considered insecure based on * the cipher suite chosen for the connection. * * @param sock the connected socket to check * * @return true if the connection of the socket * should be considered secure, or * false if it should not * * @throws IllegalArgumentException * if the argument is invalid, for example because it is * not a connected socket or was created by a different * socket factory. * Note that socket factories are not required to * check these conditions, they may simply return a default * value when called with an invalid socket argument. */ boolean isSecure(Socket sock) throws IllegalArgumentException; } ././@LongLink0100644 0000000 0000000 00000000153 12302131604 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SocketFactoryAdaptor.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/scheme/SocketFactoryAdapto0100644 0000000 0000000 00000006406 12301751672 032461 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.scheme; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpParams; @Deprecated class SocketFactoryAdaptor implements SocketFactory { private final SchemeSocketFactory factory; SocketFactoryAdaptor(final SchemeSocketFactory factory) { super(); this.factory = factory; } public Socket createSocket() throws IOException { final HttpParams params = new BasicHttpParams(); return this.factory.createSocket(params); } public Socket connectSocket( final Socket socket, final String host, final int port, final InetAddress localAddress, final int localPort, final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { InetSocketAddress local = null; if (localAddress != null || localPort > 0) { local = new InetSocketAddress(localAddress, localPort > 0 ? localPort : 0); } final InetAddress remoteAddress = InetAddress.getByName(host); final InetSocketAddress remote = new InetSocketAddress(remoteAddress, port); return this.factory.connectSocket(socket, remote, local, params); } public boolean isSecure(final Socket socket) throws IllegalArgumentException { return this.factory.isSecure(socket); } public SchemeSocketFactory getFactory() { return this.factory; } @Override public boolean equals(final Object obj) { if (obj == null) { return false; } if (this == obj) { return true; } if (obj instanceof SocketFactoryAdaptor) { return this.factory.equals(((SocketFactoryAdaptor)obj).factory); } else { return this.factory.equals(obj); } } @Override public int hashCode() { return this.factory.hashCode(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/socket/0040755 0000000 0000000 00000000000 12301751670 026644 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000156 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/socket/ConnectionSocketFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/socket/ConnectionSocketFac0100644 0000000 0000000 00000005746 12301751670 032462 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.socket; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import org.apache.http.HttpHost; import org.apache.http.protocol.HttpContext; /** * A factory for creating and connecting connection sockets. * * @since 4.3 */ public interface ConnectionSocketFactory { /** * Creates new, unconnected socket. The socket should subsequently be passed to * {@link #connectSocket(int, Socket, HttpHost, InetSocketAddress, InetSocketAddress, * HttpContext) connectSocket} method. * * @return a new socket * * @throws IOException if an I/O error occurs while creating the socket */ Socket createSocket(HttpContext context) throws IOException; /** * Connects the socket to the target host with the given resolved remote address. * * @param connectTimeout connect timeout. * @param sock the socket to connect, as obtained from {@link #createSocket(HttpContext)}. * null indicates that a new socket should be created and connected. * @param host target host as specified by the caller (end user). * @param remoteAddress the resolved remote address to connect to. * @param localAddress the local address to bind the socket to, or null for any. * @param context the actual HTTP context. * * @return the connected socket. The returned object may be different * from the sock argument if this factory supports * a layered protocol. * * @throws IOException if an I/O error occurs */ Socket connectSocket( int connectTimeout, Socket sock, HttpHost host, InetSocketAddress remoteAddress, InetSocketAddress localAddress, HttpContext context) throws IOException; } ././@LongLink0100644 0000000 0000000 00000000165 12302131604 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/socket/LayeredConnectionSocketFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/socket/LayeredConnectionSo0100644 0000000 0000000 00000004305 12301751670 032475 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.socket; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import org.apache.http.protocol.HttpContext; /** * Extended {@link ConnectionSocketFactory} interface for layered sockets such as SSL/TLS. * * @since 4.3 */ public interface LayeredConnectionSocketFactory extends ConnectionSocketFactory { /** * Returns a socket connected to the given host that is layered over an * existing socket. Used primarily for creating secure sockets through * proxies. * * @param socket the existing socket * @param target the name of the target host. * @param port the port to connect to on the target host. * @param context the actual HTTP context. * * @return Socket a new socket * * @throws IOException if an I/O error occurs while creating the socket */ Socket createLayeredSocket( Socket socket, String target, int port, HttpContext context) throws IOException, UnknownHostException; } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/socket/package-info.java0100644 0000000 0000000 00000002360 12301751670 032031 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Client connection socket APIs. */ package org.apache.http.conn.socket; ././@LongLink0100644 0000000 0000000 00000000163 12302131604 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/socket/PlainConnectionSocketFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/socket/PlainConnectionSock0100644 0000000 0000000 00000005265 12301751670 032477 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.socket; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import org.apache.http.HttpHost; import org.apache.http.annotation.Immutable; import org.apache.http.protocol.HttpContext; /** * The default class for creating plain (unencrypted) sockets. * * @since 4.3 */ @Immutable public class PlainConnectionSocketFactory implements ConnectionSocketFactory { public static final PlainConnectionSocketFactory INSTANCE = new PlainConnectionSocketFactory(); public static PlainConnectionSocketFactory getSocketFactory() { return INSTANCE; } public PlainConnectionSocketFactory() { super(); } public Socket createSocket(final HttpContext context) throws IOException { return new Socket(); } public Socket connectSocket( final int connectTimeout, final Socket socket, final HttpHost host, final InetSocketAddress remoteAddress, final InetSocketAddress localAddress, final HttpContext context) throws IOException { final Socket sock = socket != null ? socket : createSocket(context); if (localAddress != null) { sock.bind(localAddress); } try { sock.connect(remoteAddress, connectTimeout); } catch (final IOException ex) { try { sock.close(); } catch (final IOException ignore) { } throw ex; } return sock; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/0040755 0000000 0000000 00000000000 12301751671 026156 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/AbstractVerifier.java0100644 0000000 0000000 00000035316 12301751671 032265 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import java.io.IOException; import java.io.InputStream; import java.net.InetAddress; import java.net.UnknownHostException; import java.security.cert.Certificate; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.StringTokenizer; import javax.net.ssl.SSLException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.annotation.Immutable; import org.apache.http.conn.util.InetAddressUtils; /** * Abstract base class for all standard {@link X509HostnameVerifier} * implementations. * * @since 4.0 */ @Immutable public abstract class AbstractVerifier implements X509HostnameVerifier { /** * This contains a list of 2nd-level domains that aren't allowed to * have wildcards when combined with country-codes. * For example: [*.co.uk]. *

* The [*.co.uk] problem is an interesting one. Should we just hope * that CA's would never foolishly allow such a certificate to happen? * Looks like we're the only implementation guarding against this. * Firefox, Curl, Sun Java 1.4, 5, 6 don't bother with this check. */ private final static String[] BAD_COUNTRY_2LDS = { "ac", "co", "com", "ed", "edu", "go", "gouv", "gov", "info", "lg", "ne", "net", "or", "org" }; static { // Just in case developer forgot to manually sort the array. :-) Arrays.sort(BAD_COUNTRY_2LDS); } private final Log log = LogFactory.getLog(getClass()); public AbstractVerifier() { super(); } public final void verify(final String host, final SSLSocket ssl) throws IOException { if(host == null) { throw new NullPointerException("host to verify is null"); } SSLSession session = ssl.getSession(); if(session == null) { // In our experience this only happens under IBM 1.4.x when // spurious (unrelated) certificates show up in the server' // chain. Hopefully this will unearth the real problem: final InputStream in = ssl.getInputStream(); in.available(); /* If you're looking at the 2 lines of code above because you're running into a problem, you probably have two options: #1. Clean up the certificate chain that your server is presenting (e.g. edit "/etc/apache2/server.crt" or wherever it is your server's certificate chain is defined). OR #2. Upgrade to an IBM 1.5.x or greater JVM, or switch to a non-IBM JVM. */ // If ssl.getInputStream().available() didn't cause an // exception, maybe at least now the session is available? session = ssl.getSession(); if(session == null) { // If it's still null, probably a startHandshake() will // unearth the real problem. ssl.startHandshake(); // Okay, if we still haven't managed to cause an exception, // might as well go for the NPE. Or maybe we're okay now? session = ssl.getSession(); } } final Certificate[] certs = session.getPeerCertificates(); final X509Certificate x509 = (X509Certificate) certs[0]; verify(host, x509); } public final boolean verify(final String host, final SSLSession session) { try { final Certificate[] certs = session.getPeerCertificates(); final X509Certificate x509 = (X509Certificate) certs[0]; verify(host, x509); return true; } catch(final SSLException e) { return false; } } public final void verify(final String host, final X509Certificate cert) throws SSLException { final String[] cns = getCNs(cert); final String[] subjectAlts = getSubjectAlts(cert, host); verify(host, cns, subjectAlts); } public final void verify(final String host, final String[] cns, final String[] subjectAlts, final boolean strictWithSubDomains) throws SSLException { // Build the list of names we're going to check. Our DEFAULT and // STRICT implementations of the HostnameVerifier only use the // first CN provided. All other CNs are ignored. // (Firefox, wget, curl, Sun Java 1.4, 5, 6 all work this way). final LinkedList names = new LinkedList(); if(cns != null && cns.length > 0 && cns[0] != null) { names.add(cns[0]); } if(subjectAlts != null) { for (final String subjectAlt : subjectAlts) { if (subjectAlt != null) { names.add(subjectAlt); } } } if(names.isEmpty()) { final String msg = "Certificate for <" + host + "> doesn't contain CN or DNS subjectAlt"; throw new SSLException(msg); } // StringBuilder for building the error message. final StringBuilder buf = new StringBuilder(); // We're can be case-insensitive when comparing the host we used to // establish the socket to the hostname in the certificate. final String hostName = normaliseIPv6Address(host.trim().toLowerCase(Locale.US)); boolean match = false; for(final Iterator it = names.iterator(); it.hasNext();) { // Don't trim the CN, though! String cn = it.next(); cn = cn.toLowerCase(Locale.US); // Store CN in StringBuilder in case we need to report an error. buf.append(" <"); buf.append(cn); buf.append('>'); if(it.hasNext()) { buf.append(" OR"); } // The CN better have at least two dots if it wants wildcard // action. It also can't be [*.co.uk] or [*.co.jp] or // [*.org.uk], etc... final String parts[] = cn.split("\\."); final boolean doWildcard = parts.length >= 3 && parts[0].endsWith("*") && validCountryWildcard(cn) && !isIPAddress(host); if(doWildcard) { final String firstpart = parts[0]; if (firstpart.length() > 1) { // e.g. server* final String prefix = firstpart.substring(0, firstpart.length() - 1); // e.g. server final String suffix = cn.substring(firstpart.length()); // skip wildcard part from cn final String hostSuffix = hostName.substring(prefix.length()); // skip wildcard part from host match = hostName.startsWith(prefix) && hostSuffix.endsWith(suffix); } else { match = hostName.endsWith(cn.substring(1)); } if(match && strictWithSubDomains) { // If we're in strict mode, then [*.foo.com] is not // allowed to match [a.b.foo.com] match = countDots(hostName) == countDots(cn); } } else { match = hostName.equals(normaliseIPv6Address(cn)); } if(match) { break; } } if(!match) { throw new SSLException("hostname in certificate didn't match: <" + host + "> !=" + buf); } } /** * @deprecated (4.3.1) should not be a part of public APIs. */ @Deprecated public static boolean acceptableCountryWildcard(final String cn) { final String parts[] = cn.split("\\."); if (parts.length != 3 || parts[2].length() != 2) { return true; // it's not an attempt to wildcard a 2TLD within a country code } return Arrays.binarySearch(BAD_COUNTRY_2LDS, parts[1]) < 0; } boolean validCountryWildcard(final String cn) { final String parts[] = cn.split("\\."); if (parts.length != 3 || parts[2].length() != 2) { return true; // it's not an attempt to wildcard a 2TLD within a country code } return Arrays.binarySearch(BAD_COUNTRY_2LDS, parts[1]) < 0; } public static String[] getCNs(final X509Certificate cert) { final LinkedList cnList = new LinkedList(); /* Sebastian Hauer's original StrictSSLProtocolSocketFactory used getName() and had the following comment: Parses a X.500 distinguished name for the value of the "Common Name" field. This is done a bit sloppy right now and should probably be done a bit more according to RFC 2253. I've noticed that toString() seems to do a better job than getName() on these X500Principal objects, so I'm hoping that addresses Sebastian's concern. For example, getName() gives me this: 1.2.840.113549.1.9.1=#16166a756c6975736461766965734063756362632e636f6d whereas toString() gives me this: EMAILADDRESS=juliusdavies@cucbc.com Looks like toString() even works with non-ascii domain names! I tested it with "花子.co.jp" and it worked fine. */ final String subjectPrincipal = cert.getSubjectX500Principal().toString(); final StringTokenizer st = new StringTokenizer(subjectPrincipal, ",+"); while(st.hasMoreTokens()) { final String tok = st.nextToken().trim(); if (tok.length() > 3) { if (tok.substring(0, 3).equalsIgnoreCase("CN=")) { cnList.add(tok.substring(3)); } } } if(!cnList.isEmpty()) { final String[] cns = new String[cnList.size()]; cnList.toArray(cns); return cns; } else { return null; } } /** * Extracts the array of SubjectAlt DNS or IP names from an X509Certificate. * Returns null if there aren't any. * * @param cert X509Certificate * @param hostname * @return Array of SubjectALT DNS or IP names stored in the certificate. */ private static String[] getSubjectAlts( final X509Certificate cert, final String hostname) { final int subjectType; if (isIPAddress(hostname)) { subjectType = 7; } else { subjectType = 2; } final LinkedList subjectAltList = new LinkedList(); Collection> c = null; try { c = cert.getSubjectAlternativeNames(); } catch(final CertificateParsingException cpe) { } if(c != null) { for (final List aC : c) { final List list = aC; final int type = ((Integer) list.get(0)).intValue(); if (type == subjectType) { final String s = (String) list.get(1); subjectAltList.add(s); } } } if(!subjectAltList.isEmpty()) { final String[] subjectAlts = new String[subjectAltList.size()]; subjectAltList.toArray(subjectAlts); return subjectAlts; } else { return null; } } /** * Extracts the array of SubjectAlt DNS names from an X509Certificate. * Returns null if there aren't any. *

* Note: Java doesn't appear able to extract international characters * from the SubjectAlts. It can only extract international characters * from the CN field. *

* (Or maybe the version of OpenSSL I'm using to test isn't storing the * international characters correctly in the SubjectAlts?). * * @param cert X509Certificate * @return Array of SubjectALT DNS names stored in the certificate. */ public static String[] getDNSSubjectAlts(final X509Certificate cert) { return getSubjectAlts(cert, null); } /** * Counts the number of dots "." in a string. * @param s string to count dots from * @return number of dots */ public static int countDots(final String s) { int count = 0; for(int i = 0; i < s.length(); i++) { if(s.charAt(i) == '.') { count++; } } return count; } private static boolean isIPAddress(final String hostname) { return hostname != null && (InetAddressUtils.isIPv4Address(hostname) || InetAddressUtils.isIPv6Address(hostname)); } /* * Check if hostname is IPv6, and if so, convert to standard format. */ private String normaliseIPv6Address(final String hostname) { if (hostname == null || !InetAddressUtils.isIPv6Address(hostname)) { return hostname; } try { final InetAddress inetAddress = InetAddress.getByName(hostname); return inetAddress.getHostAddress(); } catch (final UnknownHostException uhe) { // Should not happen, because we check for IPv6 address above log.error("Unexpected error converting "+hostname, uhe); return hostname; } } } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/AllowAllHostnameVerifier.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/AllowAllHostnameVerifi0100644 0000000 0000000 00000003405 12301751671 032453 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import org.apache.http.annotation.Immutable; /** * The ALLOW_ALL HostnameVerifier essentially turns hostname verification * off. This implementation is a no-op, and never throws the SSLException. * * * @since 4.0 */ @Immutable public class AllowAllHostnameVerifier extends AbstractVerifier { public final void verify( final String host, final String[] cns, final String[] subjectAlts) { // Allow everything - so never blowup. } @Override public final String toString() { return "ALLOW_ALL"; } } ././@LongLink0100644 0000000 0000000 00000000161 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/BrowserCompatHostnameVerifier.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/BrowserCompatHostnameV0100644 0000000 0000000 00000004255 12301751671 032520 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import javax.net.ssl.SSLException; import org.apache.http.annotation.Immutable; /** * The HostnameVerifier that works the same way as Curl and Firefox. *

* The hostname must match either the first CN, or any of the subject-alts. * A wildcard can occur in the CN, and in any of the subject-alts. *

* The only difference between BROWSER_COMPATIBLE and STRICT is that a wildcard * (such as "*.foo.com") with BROWSER_COMPATIBLE matches all subdomains, * including "a.b.foo.com". * * * @since 4.0 */ @Immutable public class BrowserCompatHostnameVerifier extends AbstractVerifier { public final void verify( final String host, final String[] cns, final String[] subjectAlts) throws SSLException { verify(host, cns, subjectAlts, false); } @Override boolean validCountryWildcard(final String cn) { return true; } @Override public final String toString() { return "BROWSER_COMPATIBLE"; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/package-info.java0100644 0000000 0000000 00000002346 12301751671 031347 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Client TLS/SSL support. */ package org.apache.http.conn.ssl; ././@LongLink0100644 0000000 0000000 00000000145 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/PrivateKeyDetails.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/PrivateKeyDetails.java0100644 0000000 0000000 00000003627 12301751671 032417 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import org.apache.http.util.Args; import java.security.cert.X509Certificate; import java.util.Arrays; /** * Private key details. * * @since 4.3 */ public final class PrivateKeyDetails { private final String type; private final X509Certificate[] certChain; public PrivateKeyDetails(final String type, final X509Certificate[] certChain) { super(); this.type = Args.notNull(type, "Private key type"); this.certChain = certChain; } public String getType() { return type; } public X509Certificate[] getCertChain() { return certChain; } @Override public String toString() { return type + ':' + Arrays.toString(certChain); } } ././@LongLink0100644 0000000 0000000 00000000146 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/PrivateKeyStrategy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/PrivateKeyStrategy.jav0100644 0000000 0000000 00000003042 12301751671 032462 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import java.net.Socket; import java.util.Map; /** * A strategy allowing for a choice of an alias during SSL authentication. * * @since 4.3 */ public interface PrivateKeyStrategy { /** * Determines what key material to use for SSL authentication. */ String chooseAlias(Map aliases, Socket socket); } ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/SSLConnectionSocketFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/SSLConnectionSocketFac0100644 0000000 0000000 00000026657 12301751671 032362 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import org.apache.http.HttpHost; import org.apache.http.annotation.ThreadSafe; import org.apache.http.conn.socket.LayeredConnectionSocketFactory; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.TextUtils; import javax.net.SocketFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; /** * Layered socket factory for TLS/SSL connections. *

* SSLSocketFactory can be used to validate the identity of the HTTPS server against a list of * trusted certificates and to authenticate to the HTTPS server using a private key. *

* SSLSocketFactory will enable server authentication when supplied with * a {@link java.security.KeyStore trust-store} file containing one or several trusted certificates. The client * secure socket will reject the connection during the SSL session handshake if the target HTTPS * server attempts to authenticate itself with a non-trusted certificate. *

* Use JDK keytool utility to import a trusted certificate and generate a trust-store file: *

 *     keytool -import -alias "my server cert" -file server.crt -keystore my.truststore
 *    
*

* In special cases the standard trust verification process can be bypassed by using a custom * {@link org.apache.http.conn.ssl.TrustStrategy}. This interface is primarily intended for allowing self-signed * certificates to be accepted as trusted without having to add them to the trust-store file. *

* SSLSocketFactory will enable client authentication when supplied with * a {@link java.security.KeyStore key-store} file containing a private key/public certificate * pair. The client secure socket will use the private key to authenticate * itself to the target HTTPS server during the SSL session handshake if * requested to do so by the server. * The target HTTPS server will in its turn verify the certificate presented * by the client in order to establish client's authenticity. *

* Use the following sequence of actions to generate a key-store file *

*
    *
  • *

    * Use JDK keytool utility to generate a new key *

    keytool -genkey -v -alias "my client key" -validity 365 -keystore my.keystore
    * For simplicity use the same password for the key as that of the key-store *

    *
  • *
  • *

    * Issue a certificate signing request (CSR) *

    keytool -certreq -alias "my client key" -file mycertreq.csr -keystore my.keystore
    *

    *
  • *
  • *

    * Send the certificate request to the trusted Certificate Authority for signature. * One may choose to act as her own CA and sign the certificate request using a PKI * tool, such as OpenSSL. *

    *
  • *
  • *

    * Import the trusted CA root certificate *

    keytool -import -alias "my trusted ca" -file caroot.crt -keystore my.keystore
    *

    *
  • *
  • *

    * Import the PKCS#7 file containg the complete certificate chain *

    keytool -import -alias "my client key" -file mycert.p7 -keystore my.keystore
    *

    *
  • *
  • *

    * Verify the content the resultant keystore file *

    keytool -list -v -keystore my.keystore
    *

    *
  • *
* * @since 4.0 */ @ThreadSafe public class SSLConnectionSocketFactory implements LayeredConnectionSocketFactory { public static final String TLS = "TLS"; public static final String SSL = "SSL"; public static final String SSLV2 = "SSLv2"; public static final X509HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER = new AllowAllHostnameVerifier(); public static final X509HostnameVerifier BROWSER_COMPATIBLE_HOSTNAME_VERIFIER = new BrowserCompatHostnameVerifier(); public static final X509HostnameVerifier STRICT_HOSTNAME_VERIFIER = new StrictHostnameVerifier(); /** * Obtains default SSL socket factory with an SSL context based on the standard JSSE * trust material (cacerts file in the security properties directory). * System properties are not taken into consideration. * * @return default SSL socket factory */ public static SSLConnectionSocketFactory getSocketFactory() throws SSLInitializationException { return new SSLConnectionSocketFactory( SSLContexts.createDefault(), BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); } private static String[] split(final String s) { if (TextUtils.isBlank(s)) { return null; } return s.split(" *, *"); } /** * Obtains default SSL socket factory with an SSL context based on system properties * as described in * * "JavaTM Secure Socket Extension (JSSE) Reference Guide for the JavaTM 2 Platform * Standard Edition 5 * * @return default system SSL socket factory */ public static SSLConnectionSocketFactory getSystemSocketFactory() throws SSLInitializationException { return new SSLConnectionSocketFactory( (javax.net.ssl.SSLSocketFactory) javax.net.ssl.SSLSocketFactory.getDefault(), split(System.getProperty("https.protocols")), split(System.getProperty("https.cipherSuites")), BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); } private final javax.net.ssl.SSLSocketFactory socketfactory; private final X509HostnameVerifier hostnameVerifier; private final String[] supportedProtocols; private final String[] supportedCipherSuites; public SSLConnectionSocketFactory(final SSLContext sslContext) { this(sslContext, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); } public SSLConnectionSocketFactory( final SSLContext sslContext, final X509HostnameVerifier hostnameVerifier) { this(Args.notNull(sslContext, "SSL context").getSocketFactory(), null, null, hostnameVerifier); } public SSLConnectionSocketFactory( final SSLContext sslContext, final String[] supportedProtocols, final String[] supportedCipherSuites, final X509HostnameVerifier hostnameVerifier) { this(Args.notNull(sslContext, "SSL context").getSocketFactory(), supportedProtocols, supportedCipherSuites, hostnameVerifier); } public SSLConnectionSocketFactory( final javax.net.ssl.SSLSocketFactory socketfactory, final X509HostnameVerifier hostnameVerifier) { this(socketfactory, null, null, hostnameVerifier); } public SSLConnectionSocketFactory( final javax.net.ssl.SSLSocketFactory socketfactory, final String[] supportedProtocols, final String[] supportedCipherSuites, final X509HostnameVerifier hostnameVerifier) { this.socketfactory = Args.notNull(socketfactory, "SSL socket factory"); this.supportedProtocols = supportedProtocols; this.supportedCipherSuites = supportedCipherSuites; this.hostnameVerifier = hostnameVerifier != null ? hostnameVerifier : BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; } /** * Performs any custom initialization for a newly created SSLSocket * (before the SSL handshake happens). * * The default implementation is a no-op, but could be overridden to, e.g., * call {@link javax.net.ssl.SSLSocket#setEnabledCipherSuites(String[])}. */ protected void prepareSocket(final SSLSocket socket) throws IOException { } public Socket createSocket(final HttpContext context) throws IOException { return SocketFactory.getDefault().createSocket(); } public Socket connectSocket( final int connectTimeout, final Socket socket, final HttpHost host, final InetSocketAddress remoteAddress, final InetSocketAddress localAddress, final HttpContext context) throws IOException { Args.notNull(host, "HTTP host"); Args.notNull(remoteAddress, "Remote address"); final Socket sock = socket != null ? socket : createSocket(context); if (localAddress != null) { sock.bind(localAddress); } try { sock.connect(remoteAddress, connectTimeout); } catch (final IOException ex) { try { sock.close(); } catch (final IOException ignore) { } throw ex; } // Setup SSL layering if necessary if (sock instanceof SSLSocket) { final SSLSocket sslsock = (SSLSocket) sock; sslsock.startHandshake(); verifyHostname(sslsock, host.getHostName()); return sock; } else { return createLayeredSocket(sock, host.getHostName(), remoteAddress.getPort(), context); } } public Socket createLayeredSocket( final Socket socket, final String target, final int port, final HttpContext context) throws IOException { final SSLSocket sslsock = (SSLSocket) this.socketfactory.createSocket( socket, target, port, true); if (supportedProtocols != null) { sslsock.setEnabledProtocols(supportedProtocols); } if (supportedCipherSuites != null) { sslsock.setEnabledCipherSuites(supportedCipherSuites); } prepareSocket(sslsock); sslsock.startHandshake(); verifyHostname(sslsock, target); return sslsock; } X509HostnameVerifier getHostnameVerifier() { return this.hostnameVerifier; } private void verifyHostname(final SSLSocket sslsock, final String hostname) throws IOException { try { this.hostnameVerifier.verify(hostname, sslsock); // verifyHostName() didn't blowup - good! } catch (final IOException iox) { // close the socket before re-throwing the exception try { sslsock.close(); } catch (final Exception x) { /*ignore*/ } throw iox; } } } ././@LongLink0100644 0000000 0000000 00000000145 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/SSLContextBuilder.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/SSLContextBuilder.java0100644 0000000 0000000 00000022711 12301751671 032336 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import java.net.Socket; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.Principal; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509KeyManager; import javax.net.ssl.X509TrustManager; import org.apache.http.annotation.NotThreadSafe; /** * Builder for {@link SSLContext} instances. * * @since 4.3 */ @NotThreadSafe public class SSLContextBuilder { static final String TLS = "TLS"; static final String SSL = "SSL"; private String protocol; private Set keymanagers; private Set trustmanagers; private SecureRandom secureRandom; public SSLContextBuilder() { super(); this.keymanagers = new HashSet(); this.trustmanagers = new HashSet(); } public SSLContextBuilder useTLS() { this.protocol = TLS; return this; } public SSLContextBuilder useSSL() { this.protocol = SSL; return this; } public SSLContextBuilder useProtocol(final String protocol) { this.protocol = protocol; return this; } public SSLContextBuilder setSecureRandom(final SecureRandom secureRandom) { this.secureRandom = secureRandom; return this; } public SSLContextBuilder loadTrustMaterial( final KeyStore truststore, final TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyStoreException { final TrustManagerFactory tmfactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm()); tmfactory.init(truststore); final TrustManager[] tms = tmfactory.getTrustManagers(); if (tms != null) { if (trustStrategy != null) { for (int i = 0; i < tms.length; i++) { final TrustManager tm = tms[i]; if (tm instanceof X509TrustManager) { tms[i] = new TrustManagerDelegate( (X509TrustManager) tm, trustStrategy); } } } for (final TrustManager tm : tms) { this.trustmanagers.add(tm); } } return this; } public SSLContextBuilder loadTrustMaterial( final KeyStore truststore) throws NoSuchAlgorithmException, KeyStoreException { return loadTrustMaterial(truststore, null); } public SSLContextBuilder loadKeyMaterial( final KeyStore keystore, final char[] keyPassword) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException { loadKeyMaterial(keystore, keyPassword, null); return this; } public SSLContextBuilder loadKeyMaterial( final KeyStore keystore, final char[] keyPassword, final PrivateKeyStrategy aliasStrategy) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException { final KeyManagerFactory kmfactory = KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm()); kmfactory.init(keystore, keyPassword); final KeyManager[] kms = kmfactory.getKeyManagers(); if (kms != null) { if (aliasStrategy != null) { for (int i = 0; i < kms.length; i++) { final KeyManager km = kms[i]; if (km instanceof X509KeyManager) { kms[i] = new KeyManagerDelegate( (X509KeyManager) km, aliasStrategy); } } } for (final KeyManager km : kms) { keymanagers.add(km); } } return this; } public SSLContext build() throws NoSuchAlgorithmException, KeyManagementException { final SSLContext sslcontext = SSLContext.getInstance( this.protocol != null ? this.protocol : TLS); sslcontext.init( !keymanagers.isEmpty() ? keymanagers.toArray(new KeyManager[keymanagers.size()]) : null, !trustmanagers.isEmpty() ? trustmanagers.toArray(new TrustManager[trustmanagers.size()]) : null, secureRandom); return sslcontext; } static class TrustManagerDelegate implements X509TrustManager { private final X509TrustManager trustManager; private final TrustStrategy trustStrategy; TrustManagerDelegate(final X509TrustManager trustManager, final TrustStrategy trustStrategy) { super(); this.trustManager = trustManager; this.trustStrategy = trustStrategy; } public void checkClientTrusted( final X509Certificate[] chain, final String authType) throws CertificateException { this.trustManager.checkClientTrusted(chain, authType); } public void checkServerTrusted( final X509Certificate[] chain, final String authType) throws CertificateException { if (!this.trustStrategy.isTrusted(chain, authType)) { this.trustManager.checkServerTrusted(chain, authType); } } public X509Certificate[] getAcceptedIssuers() { return this.trustManager.getAcceptedIssuers(); } } static class KeyManagerDelegate implements X509KeyManager { private final X509KeyManager keyManager; private final PrivateKeyStrategy aliasStrategy; KeyManagerDelegate(final X509KeyManager keyManager, final PrivateKeyStrategy aliasStrategy) { super(); this.keyManager = keyManager; this.aliasStrategy = aliasStrategy; } public String[] getClientAliases( final String keyType, final Principal[] issuers) { return this.keyManager.getClientAliases(keyType, issuers); } public String chooseClientAlias( final String[] keyTypes, final Principal[] issuers, final Socket socket) { final Map validAliases = new HashMap(); for (final String keyType: keyTypes) { final String[] aliases = this.keyManager.getClientAliases(keyType, issuers); if (aliases != null) { for (final String alias: aliases) { validAliases.put(alias, new PrivateKeyDetails(keyType, this.keyManager.getCertificateChain(alias))); } } } return this.aliasStrategy.chooseAlias(validAliases, socket); } public String[] getServerAliases( final String keyType, final Principal[] issuers) { return this.keyManager.getServerAliases(keyType, issuers); } public String chooseServerAlias( final String keyType, final Principal[] issuers, final Socket socket) { final Map validAliases = new HashMap(); final String[] aliases = this.keyManager.getServerAliases(keyType, issuers); if (aliases != null) { for (final String alias: aliases) { validAliases.put(alias, new PrivateKeyDetails(keyType, this.keyManager.getCertificateChain(alias))); } } return this.aliasStrategy.chooseAlias(validAliases, socket); } public X509Certificate[] getCertificateChain(final String alias) { return this.keyManager.getCertificateChain(alias); } public PrivateKey getPrivateKey(final String alias) { return this.keyManager.getPrivateKey(alias); } } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/SSLContexts.java0100644 0000000 0000000 00000006174 12301751671 031217 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import javax.net.ssl.SSLContext; import org.apache.http.annotation.Immutable; /** * {@link SSLContext} factory methods. * * @since 4.3 */ @Immutable public class SSLContexts { /** * Creates default factory based on the standard JSSE trust material * (cacerts file in the security properties directory). System properties * are not taken into consideration. * * @return the default SSL socket factory */ public static SSLContext createDefault() throws SSLInitializationException { try { final SSLContext sslcontext = SSLContext.getInstance(SSLContextBuilder.TLS); sslcontext.init(null, null, null); return sslcontext; } catch (final NoSuchAlgorithmException ex) { throw new SSLInitializationException(ex.getMessage(), ex); } catch (final KeyManagementException ex) { throw new SSLInitializationException(ex.getMessage(), ex); } } /** * Creates default SSL context based on system properties. This method obtains * default SSL context by calling SSLContext.getInstance("Default"). * Please note that Default algorithm is supported as of Java 6. * This method will fall back onto {@link #createDefault()} when * Default algorithm is not available. * * @return default system SSL context */ public static SSLContext createSystemDefault() throws SSLInitializationException { try { return SSLContext.getInstance("Default"); } catch (final NoSuchAlgorithmException ex) { return createDefault(); } } /** * Creates custom SSL context. * * @return default system SSL context */ public static SSLContextBuilder custom() { return new SSLContextBuilder(); } } ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/SSLInitializationException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/SSLInitializationExcep0100644 0000000 0000000 00000002722 12301751671 032437 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; public class SSLInitializationException extends IllegalStateException { private static final long serialVersionUID = -8243587425648536702L; public SSLInitializationException(final String message, final Throwable cause) { super(message, cause); } } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/StrictHostnameVerifier.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/StrictHostnameVerifier0100644 0000000 0000000 00000004751 12301751671 032550 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import javax.net.ssl.SSLException; import org.apache.http.annotation.Immutable; /** * The Strict HostnameVerifier works the same way as Sun Java 1.4, Sun * Java 5, Sun Java 6-rc. It's also pretty close to IE6. This * implementation appears to be compliant with RFC 2818 for dealing with * wildcards. *

* The hostname must match either the first CN, or any of the subject-alts. * A wildcard can occur in the CN, and in any of the subject-alts. The * one divergence from IE6 is how we only check the first CN. IE6 allows * a match against any of the CNs present. We decided to follow in * Sun Java 1.4's footsteps and only check the first CN. (If you need * to check all the CN's, feel free to write your own implementation!). *

* A wildcard such as "*.foo.com" matches only subdomains in the same * level, for example "a.foo.com". It does not match deeper subdomains * such as "a.b.foo.com". * * * @since 4.0 */ @Immutable public class StrictHostnameVerifier extends AbstractVerifier { public final void verify( final String host, final String[] cns, final String[] subjectAlts) throws SSLException { verify(host, cns, subjectAlts, true); } @Override public final String toString() { return "STRICT"; } } ././@LongLink0100644 0000000 0000000 00000000153 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/TrustSelfSignedStrategy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/TrustSelfSignedStrateg0100644 0000000 0000000 00000003316 12301751671 032520 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; /** * A trust strategy that accepts self-signed certificates as trusted. Verification of all other * certificates is done by the trust manager configured in the SSL context. * * @since 4.1 */ public class TrustSelfSignedStrategy implements TrustStrategy { public boolean isTrusted( final X509Certificate[] chain, final String authType) throws CertificateException { return chain.length == 1; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/TrustStrategy.java0100644 0000000 0000000 00000004715 12301751671 031671 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; /** * A strategy to establish trustworthiness of certificates without consulting the trust manager * configured in the actual SSL context. This interface can be used to override the standard * JSSE certificate verification process. * * @since 4.1 */ public interface TrustStrategy { /** * Determines whether the certificate chain can be trusted without consulting the trust manager * configured in the actual SSL context. This method can be used to override the standard JSSE * certificate verification process. *

* Please note that, if this method returns false, the trust manager configured * in the actual SSL context can still clear the certificate as trusted. * * @param chain the peer certificate chain * @param authType the authentication type based on the client certificate * @return true if the certificate can be trusted without verification by * the trust manager, false otherwise. * @throws CertificateException thrown if the certificate is not trusted or invalid. */ boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException; } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/X509HostnameVerifier.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/ssl/X509HostnameVerifier.j0100644 0000000 0000000 00000006366 12301751671 032201 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import java.io.IOException; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLException; import javax.net.ssl.SSLSocket; /** * Interface for checking if a hostname matches the names stored inside the * server's X.509 certificate. This interface extends * {@link javax.net.ssl.HostnameVerifier}, but it is recommended to use * methods added by X509HostnameVerifier. * * @since 4.0 */ public interface X509HostnameVerifier extends HostnameVerifier { /** * Verifies that the host name is an acceptable match with the server's * authentication scheme based on the given {@link SSLSocket}. * * @param host the host. * @param ssl the SSL socket. * @throws IOException if an I/O error occurs or the verification process * fails. */ void verify(String host, SSLSocket ssl) throws IOException; /** * Verifies that the host name is an acceptable match with the server's * authentication scheme based on the given {@link X509Certificate}. * * @param host the host. * @param cert the certificate. * @throws SSLException if the verification process fails. */ void verify(String host, X509Certificate cert) throws SSLException; /** * Checks to see if the supplied hostname matches any of the supplied CNs * or "DNS" Subject-Alts. Most implementations only look at the first CN, * and ignore any additional CNs. Most implementations do look at all of * the "DNS" Subject-Alts. The CNs or Subject-Alts may contain wildcards * according to RFC 2818. * * @param cns CN fields, in order, as extracted from the X.509 * certificate. * @param subjectAlts Subject-Alt fields of type 2 ("DNS"), as extracted * from the X.509 certificate. * @param host The hostname to verify. * @throws SSLException if the verification process fails. */ void verify(String host, String[] cns, String[] subjectAlts) throws SSLException; } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/util/0040755 0000000 0000000 00000000000 12301751673 026334 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000145 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/util/InetAddressUtils.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/util/InetAddressUtils.java0100644 0000000 0000000 00000010771 12301751673 032430 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.util; import java.util.regex.Pattern; import org.apache.http.annotation.Immutable; /** * A collection of utilities relating to InetAddresses. * * @since 4.0 */ @Immutable public class InetAddressUtils { private InetAddressUtils() { } private static final String IPV4_BASIC_PATTERN_STRING = "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" + // initial 3 fields, 0-255 followed by . "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"; // final field, 0-255 private static final Pattern IPV4_PATTERN = Pattern.compile("^" + IPV4_BASIC_PATTERN_STRING + "$"); private static final Pattern IPV4_MAPPED_IPV6_PATTERN = // TODO does not allow for redundant leading zeros Pattern.compile("^::[fF]{4}:" + IPV4_BASIC_PATTERN_STRING + "$"); private static final Pattern IPV6_STD_PATTERN = Pattern.compile( "^[0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4}){7}$"); private static final Pattern IPV6_HEX_COMPRESSED_PATTERN = Pattern.compile( "^(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)" + // 0-6 hex fields "::" + "(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)$"); // 0-6 hex fields /* * The above pattern is not totally rigorous as it allows for more than 7 hex fields in total */ private static final char COLON_CHAR = ':'; // Must not have more than 7 colons (i.e. 8 fields) private static final int MAX_COLON_COUNT = 7; /** * Checks whether the parameter is a valid IPv4 address * * @param input the address string to check for validity * @return true if the input parameter is a valid IPv4 address */ public static boolean isIPv4Address(final String input) { return IPV4_PATTERN.matcher(input).matches(); } public static boolean isIPv4MappedIPv64Address(final String input) { return IPV4_MAPPED_IPV6_PATTERN.matcher(input).matches(); } /** * Checks whether the parameter is a valid standard (non-compressed) IPv6 address * * @param input the address string to check for validity * @return true if the input parameter is a valid standard (non-compressed) IPv6 address */ public static boolean isIPv6StdAddress(final String input) { return IPV6_STD_PATTERN.matcher(input).matches(); } /** * Checks whether the parameter is a valid compressed IPv6 address * * @param input the address string to check for validity * @return true if the input parameter is a valid compressed IPv6 address */ public static boolean isIPv6HexCompressedAddress(final String input) { int colonCount = 0; for(int i = 0; i < input.length(); i++) { if (input.charAt(i) == COLON_CHAR) { colonCount++; } } return colonCount <= MAX_COLON_COUNT && IPV6_HEX_COMPRESSED_PATTERN.matcher(input).matches(); } /** * Checks whether the parameter is a valid IPv6 address (including compressed). * * @param input the address string to check for validity * @return true if the input parameter is a valid standard or compressed IPv6 address */ public static boolean isIPv6Address(final String input) { return isIPv6StdAddress(input) || isIPv6HexCompressedAddress(input); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/conn/util/package-info.java0100644 0000000 0000000 00000002353 12301751673 031523 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Connection utility classes. */ package org.apache.http.conn.util; httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/0040755 0000000 0000000 00000000000 12301751712 025665 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/ClientCookie.java0100644 0000000 0000000 00000004674 12301751712 031110 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; /** * ClientCookie extends the standard {@link Cookie} interface with * additional client specific functionality such ability to retrieve * original cookie attributes exactly as they were specified by the * origin server. This is important for generating the Cookie * header because some cookie specifications require that the * Cookie header should include certain attributes only if * they were specified in the Set-Cookie header. * * * @since 4.0 */ public interface ClientCookie extends Cookie { // RFC2109 attributes public static final String VERSION_ATTR = "version"; public static final String PATH_ATTR = "path"; public static final String DOMAIN_ATTR = "domain"; public static final String MAX_AGE_ATTR = "max-age"; public static final String SECURE_ATTR = "secure"; public static final String COMMENT_ATTR = "comment"; public static final String EXPIRES_ATTR = "expires"; // RFC2965 attributes public static final String PORT_ATTR = "port"; public static final String COMMENTURL_ATTR = "commenturl"; public static final String DISCARD_ATTR = "discard"; String getAttribute(String name); boolean containsAttribute(String name); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/Cookie.java0100644 0000000 0000000 00000010147 12301751712 027741 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; import java.util.Date; /** * Cookie interface represents a token or short packet of state information * (also referred to as "magic-cookie") that the HTTP agent and the target * server can exchange to maintain a session. In its simples form an HTTP * cookie is merely a name / value pair. * * @since 4.0 */ public interface Cookie { /** * Returns the name. * * @return String name The name */ String getName(); /** * Returns the value. * * @return String value The current value. */ String getValue(); /** * Returns the comment describing the purpose of this cookie, or * null if no such comment has been defined. * * @return comment */ String getComment(); /** * If a user agent (web browser) presents this cookie to a user, the * cookie's purpose will be described by the information at this URL. */ String getCommentURL(); /** * Returns the expiration {@link Date} of the cookie, or null * if none exists. *

Note: the object returned by this method is * considered immutable. Changing it (e.g. using setTime()) could result * in undefined behaviour. Do so at your peril.

* @return Expiration {@link Date}, or null. */ Date getExpiryDate(); /** * Returns false if the cookie should be discarded at the end * of the "session"; true otherwise. * * @return false if the cookie should be discarded at the end * of the "session"; true otherwise */ boolean isPersistent(); /** * Returns domain attribute of the cookie. The value of the Domain * attribute specifies the domain for which the cookie is valid. * * @return the value of the domain attribute. */ String getDomain(); /** * Returns the path attribute of the cookie. The value of the Path * attribute specifies the subset of URLs on the origin server to which * this cookie applies. * * @return The value of the path attribute. */ String getPath(); /** * Get the Port attribute. It restricts the ports to which a cookie * may be returned in a Cookie request header. */ int[] getPorts(); /** * Indicates whether this cookie requires a secure connection. * * @return true if this cookie should only be sent * over secure connections, false otherwise. */ boolean isSecure(); /** * Returns the version of the cookie specification to which this * cookie conforms. * * @return the version of the cookie. */ int getVersion(); /** * Returns true if this cookie has expired. * @param date Current time * * @return true if the cookie has expired. */ boolean isExpired(final Date date); } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/CookieAttributeHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/CookieAttributeHandler.j0100644 0000000 0000000 00000005326 12301751711 032435 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; /** * This interface represents a cookie attribute handler responsible * for parsing, validating, and matching a specific cookie attribute, * such as path, domain, port, etc. * * Different cookie specifications can provide a specific * implementation for this class based on their cookie handling * rules. * * * @since 4.0 */ public interface CookieAttributeHandler { /** * Parse the given cookie attribute value and update the corresponding * {@link org.apache.http.cookie.Cookie} property. * * @param cookie {@link org.apache.http.cookie.Cookie} to be updated * @param value cookie attribute value from the cookie response header */ void parse(SetCookie cookie, String value) throws MalformedCookieException; /** * Peforms cookie validation for the given attribute value. * * @param cookie {@link org.apache.http.cookie.Cookie} to validate * @param origin the cookie source to validate against * @throws MalformedCookieException if cookie validation fails for this attribute */ void validate(Cookie cookie, CookieOrigin origin) throws MalformedCookieException; /** * Matches the given value (property of the destination host where request is being * submitted) with the corresponding cookie attribute. * * @param cookie {@link org.apache.http.cookie.Cookie} to match * @param origin the cookie source to match against * @return true if the match is successful; false otherwise */ boolean match(Cookie cookie, CookieOrigin origin); } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/CookieIdentityComparator.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/CookieIdentityComparator0100644 0000000 0000000 00000005147 12301751712 032567 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; import java.io.Serializable; import java.util.Comparator; import org.apache.http.annotation.Immutable; /** * This cookie comparator can be used to compare identity of cookies. *

* Cookies are considered identical if their names are equal and * their domain attributes match ignoring case. * * @since 4.0 */ @Immutable public class CookieIdentityComparator implements Serializable, Comparator { private static final long serialVersionUID = 4466565437490631532L; public int compare(final Cookie c1, final Cookie c2) { int res = c1.getName().compareTo(c2.getName()); if (res == 0) { // do not differentiate empty and null domains String d1 = c1.getDomain(); if (d1 == null) { d1 = ""; } else if (d1.indexOf('.') == -1) { d1 = d1 + ".local"; } String d2 = c2.getDomain(); if (d2 == null) { d2 = ""; } else if (d2.indexOf('.') == -1) { d2 = d2 + ".local"; } res = d1.compareToIgnoreCase(d2); } if (res == 0) { String p1 = c1.getPath(); if (p1 == null) { p1 = "/"; } String p2 = c2.getPath(); if (p2 == null) { p2 = "/"; } res = p1.compareTo(p2); } return res; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/CookieOrigin.java0100644 0000000 0000000 00000005371 12301751712 031114 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; import java.util.Locale; import org.apache.http.annotation.Immutable; import org.apache.http.util.Args; /** * CookieOrigin class encapsulates details of an origin server that * are relevant when parsing, validating or matching HTTP cookies. * * @since 4.0 */ @Immutable public final class CookieOrigin { private final String host; private final int port; private final String path; private final boolean secure; public CookieOrigin(final String host, final int port, final String path, final boolean secure) { super(); Args.notBlank(host, "Host"); Args.notNegative(port, "Port"); Args.notNull(path, "Path"); this.host = host.toLowerCase(Locale.ENGLISH); this.port = port; if (path.trim().length() != 0) { this.path = path; } else { this.path = "/"; } this.secure = secure; } public String getHost() { return this.host; } public String getPath() { return this.path; } public int getPort() { return this.port; } public boolean isSecure() { return this.secure; } @Override public String toString() { final StringBuilder buffer = new StringBuilder(); buffer.append('['); if (this.secure) { buffer.append("(secure)"); } buffer.append(this.host); buffer.append(':'); buffer.append(Integer.toString(this.port)); buffer.append(this.path); buffer.append(']'); return buffer.toString(); } } ././@LongLink0100644 0000000 0000000 00000000146 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/CookiePathComparator.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/CookiePathComparator.jav0100644 0000000 0000000 00000005072 12301751712 032446 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; import java.io.Serializable; import java.util.Comparator; import org.apache.http.annotation.Immutable; /** * This cookie comparator ensures that multiple cookies satisfying * a common criteria are ordered in the Cookie header such * that those with more specific Path attributes precede those with * less specific. * *

* This comparator assumes that Path attributes of two cookies * path-match a commmon request-URI. Otherwise, the result of the * comparison is undefined. *

* * * @since 4.0 */ @Immutable public class CookiePathComparator implements Serializable, Comparator { private static final long serialVersionUID = 7523645369616405818L; private String normalizePath(final Cookie cookie) { String path = cookie.getPath(); if (path == null) { path = "/"; } if (!path.endsWith("/")) { path = path + '/'; } return path; } public int compare(final Cookie c1, final Cookie c2) { final String path1 = normalizePath(c1); final String path2 = normalizePath(c2); if (path1.equals(path2)) { return 0; } else if (path1.startsWith(path2)) { return -1; } else if (path2.startsWith(path1)) { return 1; } else { // Does not really matter return 0; } } } ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/CookieRestrictionViolationException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/CookieRestrictionViolati0100644 0000000 0000000 00000003725 12301751712 032603 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; import org.apache.http.annotation.Immutable; /** * Signals that a cookie violates a restriction imposed by the cookie * specification. * * @since 4.1 */ @Immutable public class CookieRestrictionViolationException extends MalformedCookieException { private static final long serialVersionUID = 7371235577078589013L; /** * Creates a new CookeFormatViolationException with a null detail * message. */ public CookieRestrictionViolationException() { super(); } /** * Creates a new CookeRestrictionViolationException with a specified * message string. * * @param message The exception detail message */ public CookieRestrictionViolationException(final String message) { super(message); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/CookieSpec.java0100644 0000000 0000000 00000007277 12301751711 030565 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; import java.util.List; import org.apache.http.Header; /** * Defines the cookie management specification. *

Cookie management specification must define *

    *
  • rules of parsing "Set-Cookie" header *
  • rules of validation of parsed cookies *
  • formatting of "Cookie" header *
* for a given host, port and path of origin * * * @since 4.0 */ public interface CookieSpec { /** * Returns version of the state management this cookie specification * conforms to. * * @return version of the state management specification */ int getVersion(); /** * Parse the "Set-Cookie" Header into an array of Cookies. * *

This method will not perform the validation of the resultant * {@link Cookie}s

* * @see #validate * * @param header the Set-Cookie received from the server * @param origin details of the cookie origin * @return an array of Cookies parsed from the header * @throws MalformedCookieException if an exception occurs during parsing */ List parse(Header header, CookieOrigin origin) throws MalformedCookieException; /** * Validate the cookie according to validation rules defined by the * cookie specification. * * @param cookie the Cookie to validate * @param origin details of the cookie origin * @throws MalformedCookieException if the cookie is invalid */ void validate(Cookie cookie, CookieOrigin origin) throws MalformedCookieException; /** * Determines if a Cookie matches the target location. * * @param cookie the Cookie to be matched * @param origin the target to test against * * @return true if the cookie should be submitted with a request * with given attributes, false otherwise. */ boolean match(Cookie cookie, CookieOrigin origin); /** * Create "Cookie" headers for an array of Cookies. * * @param cookies the Cookies format into a Cookie header * @return a Header for the given Cookies. * @throws IllegalArgumentException if an input parameter is illegal */ List
formatCookies(List cookies); /** * Returns a request header identifying what version of the state management * specification is understood. May be null if the cookie * specification does not support Cookie2 header. */ Header getVersionHeader(); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/CookieSpecFactory.java0100644 0000000 0000000 00000003202 12301751712 032076 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; import org.apache.http.params.HttpParams; /** * Factory for {@link CookieSpec} implementations. * * @since 4.0 * * @deprecated (4.3) use {@link CookieSpecProvider} */ @Deprecated public interface CookieSpecFactory { /** * Creates an instance of {@link CookieSpec} using given HTTP parameters. * * @param params HTTP parameters. * * @return cookie spec. */ CookieSpec newInstance(HttpParams params); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/CookieSpecProvider.java0100644 0000000 0000000 00000002767 12301751711 032277 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; import org.apache.http.protocol.HttpContext; /** * Factory for {@link CookieSpec} implementations. * * @since 4.3 */ public interface CookieSpecProvider { /** * Creates an instance of {@link CookieSpec}. * * @return auth scheme. */ CookieSpec create(HttpContext context); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/CookieSpecRegistry.java0100644 0000000 0000000 00000013360 12301751712 032305 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.http.HttpRequest; import org.apache.http.annotation.ThreadSafe; import org.apache.http.config.Lookup; import org.apache.http.params.HttpParams; import org.apache.http.protocol.ExecutionContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Cookie specification registry that can be used to obtain the corresponding * cookie specification implementation for a given type of type or version of * cookie. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.config.Registry}. */ @ThreadSafe @Deprecated public final class CookieSpecRegistry implements Lookup { private final ConcurrentHashMap registeredSpecs; public CookieSpecRegistry() { super(); this.registeredSpecs = new ConcurrentHashMap(); } /** * Registers a {@link CookieSpecFactory} with the given identifier. * If a specification with the given name already exists it will be overridden. * This nameis the same one used to retrieve the {@link CookieSpecFactory} * from {@link #getCookieSpec(String)}. * * @param name the identifier for this specification * @param factory the {@link CookieSpecFactory} class to register * * @see #getCookieSpec(String) */ public void register(final String name, final CookieSpecFactory factory) { Args.notNull(name, "Name"); Args.notNull(factory, "Cookie spec factory"); registeredSpecs.put(name.toLowerCase(Locale.ENGLISH), factory); } /** * Unregisters the {@link CookieSpecFactory} with the given ID. * * @param id the identifier of the {@link CookieSpec cookie specification} to unregister */ public void unregister(final String id) { Args.notNull(id, "Id"); registeredSpecs.remove(id.toLowerCase(Locale.ENGLISH)); } /** * Gets the {@link CookieSpec cookie specification} with the given ID. * * @param name the {@link CookieSpec cookie specification} identifier * @param params the {@link HttpParams HTTP parameters} for the cookie * specification. * * @return {@link CookieSpec cookie specification} * * @throws IllegalStateException if a policy with the given name cannot be found */ public CookieSpec getCookieSpec(final String name, final HttpParams params) throws IllegalStateException { Args.notNull(name, "Name"); final CookieSpecFactory factory = registeredSpecs.get(name.toLowerCase(Locale.ENGLISH)); if (factory != null) { return factory.newInstance(params); } else { throw new IllegalStateException("Unsupported cookie spec: " + name); } } /** * Gets the {@link CookieSpec cookie specification} with the given name. * * @param name the {@link CookieSpec cookie specification} identifier * * @return {@link CookieSpec cookie specification} * * @throws IllegalStateException if a policy with the given name cannot be found */ public CookieSpec getCookieSpec(final String name) throws IllegalStateException { return getCookieSpec(name, null); } /** * Obtains a list containing the names of all registered {@link CookieSpec cookie * specs}. * * Note that the DEFAULT policy (if present) is likely to be the same * as one of the other policies, but does not have to be. * * @return list of registered cookie spec names */ public List getSpecNames(){ return new ArrayList(registeredSpecs.keySet()); } /** * Populates the internal collection of registered {@link CookieSpec cookie * specs} with the content of the map passed as a parameter. * * @param map cookie specs */ public void setItems(final Map map) { if (map == null) { return; } registeredSpecs.clear(); registeredSpecs.putAll(map); } public CookieSpecProvider lookup(final String name) { return new CookieSpecProvider() { public CookieSpec create(final HttpContext context) { final HttpRequest request = (HttpRequest) context.getAttribute( ExecutionContext.HTTP_REQUEST); return getCookieSpec(name, request.getParams()); } }; } } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/MalformedCookieException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/MalformedCookieException0100644 0000000 0000000 00000004565 12301751712 032536 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; import org.apache.http.ProtocolException; import org.apache.http.annotation.Immutable; /** * Signals that a cookie is in some way invalid or illegal in a given * context * * * @since 4.0 */ @Immutable public class MalformedCookieException extends ProtocolException { private static final long serialVersionUID = -6695462944287282185L; /** * Creates a new MalformedCookieException with a null detail message. */ public MalformedCookieException() { super(); } /** * Creates a new MalformedCookieException with a specified message string. * * @param message The exception detail message */ public MalformedCookieException(final String message) { super(message); } /** * Creates a new MalformedCookieException with the specified detail message and cause. * * @param message the exception detail message * @param cause the Throwable that caused this exception, or null * if the cause is unavailable, unknown, or not a Throwable */ public MalformedCookieException(final String message, final Throwable cause) { super(message, cause); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/package-info.java0100644 0000000 0000000 00000002357 12301751711 031057 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Client HTTP state management APIs. */ package org.apache.http.cookie; httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/SetCookie.java0100644 0000000 0000000 00000006225 12301751711 030416 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; import java.util.Date; /** * This interface represents a Set-Cookie response header sent by the * origin server to the HTTP agent in order to maintain a conversational state. * * @since 4.0 */ public interface SetCookie extends Cookie { void setValue(String value); /** * If a user agent (web browser) presents this cookie to a user, the * cookie's purpose will be described using this comment. * * @param comment * * @see #getComment() */ void setComment(String comment); /** * Sets expiration date. *

Note: the object returned by this method is considered * immutable. Changing it (e.g. using setTime()) could result in undefined * behaviour. Do so at your peril.

* * @param expiryDate the {@link Date} after which this cookie is no longer valid. * * @see Cookie#getExpiryDate * */ void setExpiryDate (Date expiryDate); /** * Sets the domain attribute. * * @param domain The value of the domain attribute * * @see Cookie#getDomain */ void setDomain(String domain); /** * Sets the path attribute. * * @param path The value of the path attribute * * @see Cookie#getPath * */ void setPath(String path); /** * Sets the secure attribute of the cookie. *

* When true the cookie should only be sent * using a secure protocol (https). This should only be set when * the cookie's originating server used a secure protocol to set the * cookie's value. * * @param secure The value of the secure attribute * * @see #isSecure() */ void setSecure (boolean secure); /** * Sets the version of the cookie specification to which this * cookie conforms. * * @param version the version of the cookie. * * @see Cookie#getVersion */ void setVersion(int version); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/SetCookie2.java0100644 0000000 0000000 00000003766 12301751712 030510 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; /** * This interface represents a Set-Cookie2 response header sent by the * origin server to the HTTP agent in order to maintain a conversational state. * * @since 4.0 */ public interface SetCookie2 extends SetCookie { /** * If a user agent (web browser) presents this cookie to a user, the * cookie's purpose will be described by the information at this URL. */ void setCommentURL(String commentURL); /** * Sets the Port attribute. It restricts the ports to which a cookie * may be returned in a Cookie request header. */ void setPorts(int[] ports); /** * Set the Discard attribute. * * Note: Discard attribute overrides Max-age. * * @see #isPersistent() */ void setDiscard(boolean discard); } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/SM.java0100644 0000000 0000000 00000003074 12301751712 027050 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; /** * Constants and static helpers related to the HTTP state management. * * * @since 4.0 */ public interface SM { public static final String COOKIE = "Cookie"; public static final String COOKIE2 = "Cookie2"; public static final String SET_COOKIE = "Set-Cookie"; public static final String SET_COOKIE2 = "Set-Cookie2"; } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/params/0040755 0000000 0000000 00000000000 12301751711 027147 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/params/CookieSpecPNames.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/params/CookieSpecPNames.0100644 0000000 0000000 00000004703 12301751711 032301 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie.params; /** * Parameter names for HTTP cookie management classes. * * @since 4.0 * * @deprecated (4.3) use constructor parameters of {@link * org.apache.http.cookie.CookieSpecProvider}s. */ @Deprecated public interface CookieSpecPNames { /** * Defines valid date patterns to be used for parsing non-standard * expires attribute. Only required for compatibility * with non-compliant servers that still use expires * defined in the Netscape draft instead of the standard * max-age attribute. *

* This parameter expects a value of type {@link java.util.Collection}. * The collection elements must be of type {@link String} compatible * with the syntax of {@link java.text.SimpleDateFormat}. *

*/ public static final String DATE_PATTERNS = "http.protocol.cookie-datepatterns"; /** * Defines whether cookies should be forced into a single * Cookie request header. Otherwise, each cookie is formatted * as a separate Cookie header. *

* This parameter expects a value of type {@link Boolean}. *

*/ public static final String SINGLE_COOKIE_HEADER = "http.protocol.single-cookie-header"; } ././@LongLink0100644 0000000 0000000 00000000145 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/params/package-info.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/cookie/params/package-info.java0100644 0000000 0000000 00000002365 12301751711 032341 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Deprecated. * @deprecated (4.3). */ package org.apache.http.cookie.params; httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/0040755 0000000 0000000 00000000000 12301751706 025360 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/0040755 0000000 0000000 00000000000 12301751702 026315 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/AuthSchemeBase.java0100644 0000000 0000000 00000013434 12301751702 032003 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import java.util.Locale; import org.apache.http.FormattedHeader; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.ChallengeState; import org.apache.http.auth.ContextAwareAuthScheme; import org.apache.http.auth.Credentials; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; /** * Abstract authentication scheme class that serves as a basis * for all authentication schemes supported by HttpClient. This class * defines the generic way of parsing an authentication challenge. It * does not make any assumptions regarding the format of the challenge * nor does it impose any specific way of responding to that challenge. * * * @since 4.0 */ @NotThreadSafe public abstract class AuthSchemeBase implements ContextAwareAuthScheme { private ChallengeState challengeState; /** * Creates an instance of AuthSchemeBase with the given challenge * state. * * @since 4.2 * * @deprecated (4.3) do not use. */ @Deprecated public AuthSchemeBase(final ChallengeState challengeState) { super(); this.challengeState = challengeState; } public AuthSchemeBase() { super(); } /** * Processes the given challenge token. Some authentication schemes * may involve multiple challenge-response exchanges. Such schemes must be able * to maintain the state information when dealing with sequential challenges * * @param header the challenge header * * @throws MalformedChallengeException is thrown if the authentication challenge * is malformed */ public void processChallenge(final Header header) throws MalformedChallengeException { Args.notNull(header, "Header"); final String authheader = header.getName(); if (authheader.equalsIgnoreCase(AUTH.WWW_AUTH)) { this.challengeState = ChallengeState.TARGET; } else if (authheader.equalsIgnoreCase(AUTH.PROXY_AUTH)) { this.challengeState = ChallengeState.PROXY; } else { throw new MalformedChallengeException("Unexpected header name: " + authheader); } final CharArrayBuffer buffer; int pos; if (header instanceof FormattedHeader) { buffer = ((FormattedHeader) header).getBuffer(); pos = ((FormattedHeader) header).getValuePos(); } else { final String s = header.getValue(); if (s == null) { throw new MalformedChallengeException("Header value is null"); } buffer = new CharArrayBuffer(s.length()); buffer.append(s); pos = 0; } while (pos < buffer.length() && HTTP.isWhitespace(buffer.charAt(pos))) { pos++; } final int beginIndex = pos; while (pos < buffer.length() && !HTTP.isWhitespace(buffer.charAt(pos))) { pos++; } final int endIndex = pos; final String s = buffer.substring(beginIndex, endIndex); if (!s.equalsIgnoreCase(getSchemeName())) { throw new MalformedChallengeException("Invalid scheme identifier: " + s); } parseChallenge(buffer, pos, buffer.length()); } @SuppressWarnings("deprecation") public Header authenticate( final Credentials credentials, final HttpRequest request, final HttpContext context) throws AuthenticationException { return authenticate(credentials, request); } protected abstract void parseChallenge( CharArrayBuffer buffer, int beginIndex, int endIndex) throws MalformedChallengeException; /** * Returns true if authenticating against a proxy, false * otherwise. */ public boolean isProxy() { return this.challengeState != null && this.challengeState == ChallengeState.PROXY; } /** * Returns {@link ChallengeState} value or null if unchallenged. * * @since 4.2 */ public ChallengeState getChallengeState() { return this.challengeState; } @Override public String toString() { final String name = getSchemeName(); if (name != null) { return name.toUpperCase(Locale.US); } else { return super.toString(); } } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/BasicScheme.java0100644 0000000 0000000 00000016260 12301751702 031330 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import java.nio.charset.Charset; import org.apache.commons.codec.binary.Base64; import org.apache.http.Consts; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.ChallengeState; import org.apache.http.auth.Credentials; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.message.BufferedHeader; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; import org.apache.http.util.EncodingUtils; /** * Basic authentication scheme as defined in RFC 2617. * * @since 4.0 */ @NotThreadSafe public class BasicScheme extends RFC2617Scheme { private final Base64 base64codec; /** Whether the basic authentication process is complete */ private boolean complete; /** * @since 4.3 */ public BasicScheme(final Charset credentialsCharset) { super(credentialsCharset); this.base64codec = new Base64(0); this.complete = false; } /** * Creates an instance of BasicScheme with the given challenge * state. * * @since 4.2 * * @deprecated (4.3) do not use. */ @Deprecated public BasicScheme(final ChallengeState challengeState) { super(challengeState); this.base64codec = new Base64(0); } public BasicScheme() { this(Consts.ASCII); } /** * Returns textual designation of the basic authentication scheme. * * @return basic */ public String getSchemeName() { return "basic"; } /** * Processes the Basic challenge. * * @param header the challenge header * * @throws MalformedChallengeException is thrown if the authentication challenge * is malformed */ @Override public void processChallenge( final Header header) throws MalformedChallengeException { super.processChallenge(header); this.complete = true; } /** * Tests if the Basic authentication process has been completed. * * @return true if Basic authorization has been processed, * false otherwise. */ public boolean isComplete() { return this.complete; } /** * Returns false. Basic authentication scheme is request based. * * @return false. */ public boolean isConnectionBased() { return false; } /** * @deprecated (4.2) Use {@link org.apache.http.auth.ContextAwareAuthScheme#authenticate( * Credentials, HttpRequest, org.apache.http.protocol.HttpContext)} */ @Deprecated public Header authenticate( final Credentials credentials, final HttpRequest request) throws AuthenticationException { return authenticate(credentials, request, new BasicHttpContext()); } /** * Produces basic authorization header for the given set of {@link Credentials}. * * @param credentials The set of credentials to be used for authentication * @param request The request being authenticated * @throws org.apache.http.auth.InvalidCredentialsException if authentication * credentials are not valid or not applicable for this authentication scheme * @throws AuthenticationException if authorization string cannot * be generated due to an authentication failure * * @return a basic authorization string */ @Override public Header authenticate( final Credentials credentials, final HttpRequest request, final HttpContext context) throws AuthenticationException { Args.notNull(credentials, "Credentials"); Args.notNull(request, "HTTP request"); final StringBuilder tmp = new StringBuilder(); tmp.append(credentials.getUserPrincipal().getName()); tmp.append(":"); tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword()); final byte[] base64password = base64codec.encode( EncodingUtils.getBytes(tmp.toString(), getCredentialsCharset(request))); final CharArrayBuffer buffer = new CharArrayBuffer(32); if (isProxy()) { buffer.append(AUTH.PROXY_AUTH_RESP); } else { buffer.append(AUTH.WWW_AUTH_RESP); } buffer.append(": Basic "); buffer.append(base64password, 0, base64password.length); return new BufferedHeader(buffer); } /** * Returns a basic Authorization header value for the given * {@link Credentials} and charset. * * @param credentials The credentials to encode. * @param charset The charset to use for encoding the credentials * * @return a basic authorization header * * @deprecated (4.3) use {@link #authenticate(Credentials, HttpRequest, HttpContext)}. */ @Deprecated public static Header authenticate( final Credentials credentials, final String charset, final boolean proxy) { Args.notNull(credentials, "Credentials"); Args.notNull(charset, "charset"); final StringBuilder tmp = new StringBuilder(); tmp.append(credentials.getUserPrincipal().getName()); tmp.append(":"); tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword()); final byte[] base64password = Base64.encodeBase64( EncodingUtils.getBytes(tmp.toString(), charset), false); final CharArrayBuffer buffer = new CharArrayBuffer(32); if (proxy) { buffer.append(AUTH.PROXY_AUTH_RESP); } else { buffer.append(AUTH.WWW_AUTH_RESP); } buffer.append(": Basic "); buffer.append(base64password, 0, base64password.length); return new BufferedHeader(buffer); } } ././@LongLink0100644 0000000 0000000 00000000147 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/BasicSchemeFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/BasicSchemeFactory.ja0100644 0000000 0000000 00000004301 12301751702 032322 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import java.nio.charset.Charset; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeFactory; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; /** * {@link AuthSchemeProvider} implementation that creates and initializes * {@link BasicScheme} instances. * * @since 4.0 */ @Immutable @SuppressWarnings("deprecation") public class BasicSchemeFactory implements AuthSchemeFactory, AuthSchemeProvider { private final Charset charset; /** * @since 4.3 */ public BasicSchemeFactory(final Charset charset) { super(); this.charset = charset; } public BasicSchemeFactory() { this(null); } public AuthScheme newInstance(final HttpParams params) { return new BasicScheme(); } public AuthScheme create(final HttpContext context) { return new BasicScheme(this.charset); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/DigestScheme.java0100644 0000000 0000000 00000041541 12301751702 031526 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import java.io.IOException; import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Formatter; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; import java.util.StringTokenizer; import org.apache.http.Consts; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.ChallengeState; import org.apache.http.auth.Credentials; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.message.BasicHeaderValueFormatter; import org.apache.http.message.BasicNameValuePair; import org.apache.http.message.BufferedHeader; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; import org.apache.http.util.EncodingUtils; /** * Digest authentication scheme as defined in RFC 2617. * Both MD5 (default) and MD5-sess are supported. * Currently only qop=auth or no qop is supported. qop=auth-int * is unsupported. If auth and auth-int are provided, auth is * used. *

* Since the digest username is included as clear text in the generated * Authentication header, the charset of the username must be compatible * with the HTTP element charset used by the connection. * * @since 4.0 */ @NotThreadSafe public class DigestScheme extends RFC2617Scheme { /** * Hexa values used when creating 32 character long digest in HTTP DigestScheme * in case of authentication. * * @see #encode(byte[]) */ private static final char[] HEXADECIMAL = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; /** Whether the digest authentication process is complete */ private boolean complete; private static final int QOP_UNKNOWN = -1; private static final int QOP_MISSING = 0; private static final int QOP_AUTH_INT = 1; private static final int QOP_AUTH = 2; private String lastNonce; private long nounceCount; private String cnonce; private String a1; private String a2; /** * @since 4.3 */ public DigestScheme(final Charset credentialsCharset) { super(credentialsCharset); this.complete = false; } /** * Creates an instance of DigestScheme with the given challenge * state. * * @since 4.2 * * @deprecated (4.3) do not use. */ @Deprecated public DigestScheme(final ChallengeState challengeState) { super(challengeState); } public DigestScheme() { this(Consts.ASCII); } /** * Processes the Digest challenge. * * @param header the challenge header * * @throws MalformedChallengeException is thrown if the authentication challenge * is malformed */ @Override public void processChallenge( final Header header) throws MalformedChallengeException { super.processChallenge(header); this.complete = true; } /** * Tests if the Digest authentication process has been completed. * * @return true if Digest authorization has been processed, * false otherwise. */ public boolean isComplete() { final String s = getParameter("stale"); if ("true".equalsIgnoreCase(s)) { return false; } else { return this.complete; } } /** * Returns textual designation of the digest authentication scheme. * * @return digest */ public String getSchemeName() { return "digest"; } /** * Returns false. Digest authentication scheme is request based. * * @return false. */ public boolean isConnectionBased() { return false; } public void overrideParamter(final String name, final String value) { getParameters().put(name, value); } /** * @deprecated (4.2) Use {@link org.apache.http.auth.ContextAwareAuthScheme#authenticate( * Credentials, HttpRequest, org.apache.http.protocol.HttpContext)} */ @Deprecated public Header authenticate( final Credentials credentials, final HttpRequest request) throws AuthenticationException { return authenticate(credentials, request, new BasicHttpContext()); } /** * Produces a digest authorization string for the given set of * {@link Credentials}, method name and URI. * * @param credentials A set of credentials to be used for athentication * @param request The request being authenticated * * @throws org.apache.http.auth.InvalidCredentialsException if authentication credentials * are not valid or not applicable for this authentication scheme * @throws AuthenticationException if authorization string cannot * be generated due to an authentication failure * * @return a digest authorization string */ @Override public Header authenticate( final Credentials credentials, final HttpRequest request, final HttpContext context) throws AuthenticationException { Args.notNull(credentials, "Credentials"); Args.notNull(request, "HTTP request"); if (getParameter("realm") == null) { throw new AuthenticationException("missing realm in challenge"); } if (getParameter("nonce") == null) { throw new AuthenticationException("missing nonce in challenge"); } // Add method name and request-URI to the parameter map getParameters().put("methodname", request.getRequestLine().getMethod()); getParameters().put("uri", request.getRequestLine().getUri()); final String charset = getParameter("charset"); if (charset == null) { getParameters().put("charset", getCredentialsCharset(request)); } return createDigestHeader(credentials, request); } private static MessageDigest createMessageDigest( final String digAlg) throws UnsupportedDigestAlgorithmException { try { return MessageDigest.getInstance(digAlg); } catch (final Exception e) { throw new UnsupportedDigestAlgorithmException( "Unsupported algorithm in HTTP Digest authentication: " + digAlg); } } /** * Creates digest-response header as defined in RFC2617. * * @param credentials User credentials * * @return The digest-response as String. */ private Header createDigestHeader( final Credentials credentials, final HttpRequest request) throws AuthenticationException { final String uri = getParameter("uri"); final String realm = getParameter("realm"); final String nonce = getParameter("nonce"); final String opaque = getParameter("opaque"); final String method = getParameter("methodname"); String algorithm = getParameter("algorithm"); // If an algorithm is not specified, default to MD5. if (algorithm == null) { algorithm = "MD5"; } final Set qopset = new HashSet(8); int qop = QOP_UNKNOWN; final String qoplist = getParameter("qop"); if (qoplist != null) { final StringTokenizer tok = new StringTokenizer(qoplist, ","); while (tok.hasMoreTokens()) { final String variant = tok.nextToken().trim(); qopset.add(variant.toLowerCase(Locale.US)); } if (request instanceof HttpEntityEnclosingRequest && qopset.contains("auth-int")) { qop = QOP_AUTH_INT; } else if (qopset.contains("auth")) { qop = QOP_AUTH; } } else { qop = QOP_MISSING; } if (qop == QOP_UNKNOWN) { throw new AuthenticationException("None of the qop methods is supported: " + qoplist); } String charset = getParameter("charset"); if (charset == null) { charset = "ISO-8859-1"; } String digAlg = algorithm; if (digAlg.equalsIgnoreCase("MD5-sess")) { digAlg = "MD5"; } final MessageDigest digester; try { digester = createMessageDigest(digAlg); } catch (final UnsupportedDigestAlgorithmException ex) { throw new AuthenticationException("Unsuppported digest algorithm: " + digAlg); } final String uname = credentials.getUserPrincipal().getName(); final String pwd = credentials.getPassword(); if (nonce.equals(this.lastNonce)) { nounceCount++; } else { nounceCount = 1; cnonce = null; lastNonce = nonce; } final StringBuilder sb = new StringBuilder(256); final Formatter formatter = new Formatter(sb, Locale.US); formatter.format("%08x", nounceCount); formatter.close(); final String nc = sb.toString(); if (cnonce == null) { cnonce = createCnonce(); } a1 = null; a2 = null; // 3.2.2.2: Calculating digest if (algorithm.equalsIgnoreCase("MD5-sess")) { // H( unq(username-value) ":" unq(realm-value) ":" passwd ) // ":" unq(nonce-value) // ":" unq(cnonce-value) // calculated one per session sb.setLength(0); sb.append(uname).append(':').append(realm).append(':').append(pwd); final String checksum = encode(digester.digest(EncodingUtils.getBytes(sb.toString(), charset))); sb.setLength(0); sb.append(checksum).append(':').append(nonce).append(':').append(cnonce); a1 = sb.toString(); } else { // unq(username-value) ":" unq(realm-value) ":" passwd sb.setLength(0); sb.append(uname).append(':').append(realm).append(':').append(pwd); a1 = sb.toString(); } final String hasha1 = encode(digester.digest(EncodingUtils.getBytes(a1, charset))); if (qop == QOP_AUTH) { // Method ":" digest-uri-value a2 = method + ':' + uri; } else if (qop == QOP_AUTH_INT) { // Method ":" digest-uri-value ":" H(entity-body) HttpEntity entity = null; if (request instanceof HttpEntityEnclosingRequest) { entity = ((HttpEntityEnclosingRequest) request).getEntity(); } if (entity != null && !entity.isRepeatable()) { // If the entity is not repeatable, try falling back onto QOP_AUTH if (qopset.contains("auth")) { qop = QOP_AUTH; a2 = method + ':' + uri; } else { throw new AuthenticationException("Qop auth-int cannot be used with " + "a non-repeatable entity"); } } else { final HttpEntityDigester entityDigester = new HttpEntityDigester(digester); try { if (entity != null) { entity.writeTo(entityDigester); } entityDigester.close(); } catch (final IOException ex) { throw new AuthenticationException("I/O error reading entity content", ex); } a2 = method + ':' + uri + ':' + encode(entityDigester.getDigest()); } } else { a2 = method + ':' + uri; } final String hasha2 = encode(digester.digest(EncodingUtils.getBytes(a2, charset))); // 3.2.2.1 final String digestValue; if (qop == QOP_MISSING) { sb.setLength(0); sb.append(hasha1).append(':').append(nonce).append(':').append(hasha2); digestValue = sb.toString(); } else { sb.setLength(0); sb.append(hasha1).append(':').append(nonce).append(':').append(nc).append(':') .append(cnonce).append(':').append(qop == QOP_AUTH_INT ? "auth-int" : "auth") .append(':').append(hasha2); digestValue = sb.toString(); } final String digest = encode(digester.digest(EncodingUtils.getAsciiBytes(digestValue))); final CharArrayBuffer buffer = new CharArrayBuffer(128); if (isProxy()) { buffer.append(AUTH.PROXY_AUTH_RESP); } else { buffer.append(AUTH.WWW_AUTH_RESP); } buffer.append(": Digest "); final List params = new ArrayList(20); params.add(new BasicNameValuePair("username", uname)); params.add(new BasicNameValuePair("realm", realm)); params.add(new BasicNameValuePair("nonce", nonce)); params.add(new BasicNameValuePair("uri", uri)); params.add(new BasicNameValuePair("response", digest)); if (qop != QOP_MISSING) { params.add(new BasicNameValuePair("qop", qop == QOP_AUTH_INT ? "auth-int" : "auth")); params.add(new BasicNameValuePair("nc", nc)); params.add(new BasicNameValuePair("cnonce", cnonce)); } // algorithm cannot be null here params.add(new BasicNameValuePair("algorithm", algorithm)); if (opaque != null) { params.add(new BasicNameValuePair("opaque", opaque)); } for (int i = 0; i < params.size(); i++) { final BasicNameValuePair param = params.get(i); if (i > 0) { buffer.append(", "); } final String name = param.getName(); final boolean noQuotes = ("nc".equals(name) || "qop".equals(name) || "algorithm".equals(name)); BasicHeaderValueFormatter.INSTANCE.formatNameValuePair(buffer, param, !noQuotes); } return new BufferedHeader(buffer); } String getCnonce() { return cnonce; } String getA1() { return a1; } String getA2() { return a2; } /** * Encodes the 128 bit (16 bytes) MD5 digest into a 32 characters long * String according to RFC 2617. * * @param binaryData array containing the digest * @return encoded MD5, or null if encoding failed */ static String encode(final byte[] binaryData) { final int n = binaryData.length; final char[] buffer = new char[n * 2]; for (int i = 0; i < n; i++) { final int low = (binaryData[i] & 0x0f); final int high = ((binaryData[i] & 0xf0) >> 4); buffer[i * 2] = HEXADECIMAL[high]; buffer[(i * 2) + 1] = HEXADECIMAL[low]; } return new String(buffer); } /** * Creates a random cnonce value based on the current time. * * @return The cnonce value as String. */ public static String createCnonce() { final SecureRandom rnd = new SecureRandom(); final byte[] tmp = new byte[8]; rnd.nextBytes(tmp); return encode(tmp); } @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append("DIGEST [complete=").append(complete) .append(", nonce=").append(lastNonce) .append(", nc=").append(nounceCount) .append("]"); return builder.toString(); } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/DigestSchemeFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/DigestSchemeFactory.j0100644 0000000 0000000 00000004307 12301751702 032365 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import java.nio.charset.Charset; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeFactory; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; /** * {@link AuthSchemeProvider} implementation that creates and initializes * {@link DigestScheme} instances. * * @since 4.0 */ @Immutable @SuppressWarnings("deprecation") public class DigestSchemeFactory implements AuthSchemeFactory, AuthSchemeProvider { private final Charset charset; /** * @since 4.3 */ public DigestSchemeFactory(final Charset charset) { super(); this.charset = charset; } public DigestSchemeFactory() { this(null); } public AuthScheme newInstance(final HttpParams params) { return new DigestScheme(); } public AuthScheme create(final HttpContext context) { return new DigestScheme(this.charset); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/GGSSchemeBase.java0100644 0000000 0000000 00000020127 12301751702 031517 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import org.apache.commons.codec.binary.Base64; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.Credentials; import org.apache.http.auth.InvalidCredentialsException; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.message.BufferedHeader; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; import org.ietf.jgss.GSSContext; import org.ietf.jgss.GSSException; import org.ietf.jgss.GSSManager; import org.ietf.jgss.GSSName; import org.ietf.jgss.Oid; /** * @since 4.2 */ @NotThreadSafe public abstract class GGSSchemeBase extends AuthSchemeBase { enum State { UNINITIATED, CHALLENGE_RECEIVED, TOKEN_GENERATED, FAILED, } private final Log log = LogFactory.getLog(getClass()); private final Base64 base64codec; private final boolean stripPort; /** Authentication process state */ private State state; /** base64 decoded challenge **/ private byte[] token; GGSSchemeBase(final boolean stripPort) { super(); this.base64codec = new Base64(0); this.stripPort = stripPort; this.state = State.UNINITIATED; } GGSSchemeBase() { this(false); } protected GSSManager getManager() { return GSSManager.getInstance(); } protected byte[] generateGSSToken( final byte[] input, final Oid oid, final String authServer) throws GSSException { byte[] token = input; if (token == null) { token = new byte[0]; } final GSSManager manager = getManager(); final GSSName serverName = manager.createName("HTTP@" + authServer, GSSName.NT_HOSTBASED_SERVICE); final GSSContext gssContext = manager.createContext( serverName.canonicalize(oid), oid, null, GSSContext.DEFAULT_LIFETIME); gssContext.requestMutualAuth(true); gssContext.requestCredDeleg(true); return gssContext.initSecContext(token, 0, token.length); } protected abstract byte[] generateToken( byte[] input, final String authServer) throws GSSException; public boolean isComplete() { return this.state == State.TOKEN_GENERATED || this.state == State.FAILED; } /** * @deprecated (4.2) Use {@link org.apache.http.auth.ContextAwareAuthScheme#authenticate( * Credentials, HttpRequest, org.apache.http.protocol.HttpContext)} */ @Deprecated public Header authenticate( final Credentials credentials, final HttpRequest request) throws AuthenticationException { return authenticate(credentials, request, null); } @Override public Header authenticate( final Credentials credentials, final HttpRequest request, final HttpContext context) throws AuthenticationException { Args.notNull(request, "HTTP request"); switch (state) { case UNINITIATED: throw new AuthenticationException(getSchemeName() + " authentication has not been initiated"); case FAILED: throw new AuthenticationException(getSchemeName() + " authentication has failed"); case CHALLENGE_RECEIVED: try { final HttpRoute route = (HttpRoute) context.getAttribute(HttpClientContext.HTTP_ROUTE); if (route == null) { throw new AuthenticationException("Connection route is not available"); } HttpHost host; if (isProxy()) { host = route.getProxyHost(); if (host == null) { host = route.getTargetHost(); } } else { host = route.getTargetHost(); } final String authServer; if (!this.stripPort && host.getPort() > 0) { authServer = host.toHostString(); } else { authServer = host.getHostName(); } if (log.isDebugEnabled()) { log.debug("init " + authServer); } token = generateToken(token, authServer); state = State.TOKEN_GENERATED; } catch (final GSSException gsse) { state = State.FAILED; if (gsse.getMajor() == GSSException.DEFECTIVE_CREDENTIAL || gsse.getMajor() == GSSException.CREDENTIALS_EXPIRED) { throw new InvalidCredentialsException(gsse.getMessage(), gsse); } if (gsse.getMajor() == GSSException.NO_CRED ) { throw new InvalidCredentialsException(gsse.getMessage(), gsse); } if (gsse.getMajor() == GSSException.DEFECTIVE_TOKEN || gsse.getMajor() == GSSException.DUPLICATE_TOKEN || gsse.getMajor() == GSSException.OLD_TOKEN) { throw new AuthenticationException(gsse.getMessage(), gsse); } // other error throw new AuthenticationException(gsse.getMessage()); } case TOKEN_GENERATED: final String tokenstr = new String(base64codec.encode(token)); if (log.isDebugEnabled()) { log.debug("Sending response '" + tokenstr + "' back to the auth server"); } final CharArrayBuffer buffer = new CharArrayBuffer(32); if (isProxy()) { buffer.append(AUTH.PROXY_AUTH_RESP); } else { buffer.append(AUTH.WWW_AUTH_RESP); } buffer.append(": Negotiate "); buffer.append(tokenstr); return new BufferedHeader(buffer); default: throw new IllegalStateException("Illegal state: " + state); } } @Override protected void parseChallenge( final CharArrayBuffer buffer, final int beginIndex, final int endIndex) throws MalformedChallengeException { final String challenge = buffer.substringTrimmed(beginIndex, endIndex); if (log.isDebugEnabled()) { log.debug("Received challenge '" + challenge + "' from the auth server"); } if (state == State.UNINITIATED) { token = Base64.decodeBase64(challenge.getBytes()); state = State.CHALLENGE_RECEIVED; } else { log.debug("Authentication already attempted"); state = State.FAILED; } } } ././@LongLink0100644 0000000 0000000 00000000146 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/HttpAuthenticator.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/HttpAuthenticator.jav0100644 0000000 0000000 00000022720 12301751702 032471 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import java.io.IOException; import java.util.Locale; import java.util.Map; import java.util.Queue; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.auth.AuthOption; import org.apache.http.auth.AuthProtocolState; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthState; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.ContextAwareAuthScheme; import org.apache.http.auth.Credentials; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.client.AuthenticationStrategy; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Asserts; /** * @since 4.3 */ public class HttpAuthenticator { private final Log log; public HttpAuthenticator(final Log log) { super(); this.log = log != null ? log : LogFactory.getLog(getClass()); } public HttpAuthenticator() { this(null); } public boolean isAuthenticationRequested( final HttpHost host, final HttpResponse response, final AuthenticationStrategy authStrategy, final AuthState authState, final HttpContext context) { if (authStrategy.isAuthenticationRequested(host, response, context)) { this.log.debug("Authentication required"); if (authState.getState() == AuthProtocolState.SUCCESS) { authStrategy.authFailed(host, authState.getAuthScheme(), context); } return true; } else { switch (authState.getState()) { case CHALLENGED: case HANDSHAKE: this.log.debug("Authentication succeeded"); authState.setState(AuthProtocolState.SUCCESS); authStrategy.authSucceeded(host, authState.getAuthScheme(), context); break; case SUCCESS: break; default: authState.setState(AuthProtocolState.UNCHALLENGED); } return false; } } public boolean handleAuthChallenge( final HttpHost host, final HttpResponse response, final AuthenticationStrategy authStrategy, final AuthState authState, final HttpContext context) { try { if (this.log.isDebugEnabled()) { this.log.debug(host.toHostString() + " requested authentication"); } final Map challenges = authStrategy.getChallenges(host, response, context); if (challenges.isEmpty()) { this.log.debug("Response contains no authentication challenges"); return false; } final AuthScheme authScheme = authState.getAuthScheme(); switch (authState.getState()) { case FAILURE: return false; case SUCCESS: authState.reset(); break; case CHALLENGED: case HANDSHAKE: if (authScheme == null) { this.log.debug("Auth scheme is null"); authStrategy.authFailed(host, null, context); authState.reset(); authState.setState(AuthProtocolState.FAILURE); return false; } case UNCHALLENGED: if (authScheme != null) { final String id = authScheme.getSchemeName(); final Header challenge = challenges.get(id.toLowerCase(Locale.US)); if (challenge != null) { this.log.debug("Authorization challenge processed"); authScheme.processChallenge(challenge); if (authScheme.isComplete()) { this.log.debug("Authentication failed"); authStrategy.authFailed(host, authState.getAuthScheme(), context); authState.reset(); authState.setState(AuthProtocolState.FAILURE); return false; } else { authState.setState(AuthProtocolState.HANDSHAKE); return true; } } else { authState.reset(); // Retry authentication with a different scheme } } } final Queue authOptions = authStrategy.select(challenges, host, response, context); if (authOptions != null && !authOptions.isEmpty()) { if (this.log.isDebugEnabled()) { this.log.debug("Selected authentication options: " + authOptions); } authState.setState(AuthProtocolState.CHALLENGED); authState.update(authOptions); return true; } else { return false; } } catch (final MalformedChallengeException ex) { if (this.log.isWarnEnabled()) { this.log.warn("Malformed challenge: " + ex.getMessage()); } authState.reset(); return false; } } public void generateAuthResponse( final HttpRequest request, final AuthState authState, final HttpContext context) throws HttpException, IOException { AuthScheme authScheme = authState.getAuthScheme(); Credentials creds = authState.getCredentials(); switch (authState.getState()) { case FAILURE: return; case SUCCESS: ensureAuthScheme(authScheme); if (authScheme.isConnectionBased()) { return; } break; case CHALLENGED: final Queue authOptions = authState.getAuthOptions(); if (authOptions != null) { while (!authOptions.isEmpty()) { final AuthOption authOption = authOptions.remove(); authScheme = authOption.getAuthScheme(); creds = authOption.getCredentials(); authState.update(authScheme, creds); if (this.log.isDebugEnabled()) { this.log.debug("Generating response to an authentication challenge using " + authScheme.getSchemeName() + " scheme"); } try { final Header header = doAuth(authScheme, creds, request, context); request.addHeader(header); break; } catch (final AuthenticationException ex) { if (this.log.isWarnEnabled()) { this.log.warn(authScheme + " authentication error: " + ex.getMessage()); } } } return; } else { ensureAuthScheme(authScheme); } } if (authScheme != null) { try { final Header header = doAuth(authScheme, creds, request, context); request.addHeader(header); } catch (final AuthenticationException ex) { if (this.log.isErrorEnabled()) { this.log.error(authScheme + " authentication error: " + ex.getMessage()); } } } } private void ensureAuthScheme(final AuthScheme authScheme) { Asserts.notNull(authScheme, "Auth scheme"); } @SuppressWarnings("deprecation") private Header doAuth( final AuthScheme authScheme, final Credentials creds, final HttpRequest request, final HttpContext context) throws AuthenticationException { if (authScheme instanceof ContextAwareAuthScheme) { return ((ContextAwareAuthScheme) authScheme).authenticate(creds, request, context); } else { return authScheme.authenticate(creds, request); } } } ././@LongLink0100644 0000000 0000000 00000000147 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/HttpEntityDigester.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/HttpEntityDigester.ja0100644 0000000 0000000 00000004510 12301751702 032431 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import java.io.IOException; import java.io.OutputStream; import java.security.MessageDigest; class HttpEntityDigester extends OutputStream { private final MessageDigest digester; private boolean closed; private byte[] digest; HttpEntityDigester(final MessageDigest digester) { super(); this.digester = digester; this.digester.reset(); } @Override public void write(final int b) throws IOException { if (this.closed) { throw new IOException("Stream has been already closed"); } this.digester.update((byte) b); } @Override public void write(final byte[] b, final int off, final int len) throws IOException { if (this.closed) { throw new IOException("Stream has been already closed"); } this.digester.update(b, off, len); } @Override public void close() throws IOException { if (this.closed) { return; } this.closed = true; this.digest = this.digester.digest(); super.close(); } public byte[] getDigest() { return this.digest; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/KerberosScheme.java0100644 0000000 0000000 00000007074 12301751702 032066 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.Credentials; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.ietf.jgss.GSSException; import org.ietf.jgss.Oid; /** * KERBEROS authentication scheme. * * @since 4.2 */ @NotThreadSafe public class KerberosScheme extends GGSSchemeBase { private static final String KERBEROS_OID = "1.2.840.113554.1.2.2"; public KerberosScheme(final boolean stripPort) { super(stripPort); } public KerberosScheme() { super(false); } public String getSchemeName() { return "Kerberos"; } /** * Produces KERBEROS authorization Header based on token created by * processChallenge. * * @param credentials not used by the KERBEROS scheme. * @param request The request being authenticated * * @throws AuthenticationException if authentication string cannot * be generated due to an authentication failure * * @return KERBEROS authentication Header */ @Override public Header authenticate( final Credentials credentials, final HttpRequest request, final HttpContext context) throws AuthenticationException { return super.authenticate(credentials, request, context); } @Override protected byte[] generateToken(final byte[] input, final String authServer) throws GSSException { return generateGSSToken(input, new Oid(KERBEROS_OID), authServer); } /** * There are no valid parameters for KERBEROS authentication so this * method always returns null. * * @return null */ public String getParameter(final String name) { Args.notNull(name, "Parameter name"); return null; } /** * The concept of an authentication realm is not supported by the Negotiate * authentication scheme. Always returns null. * * @return null */ public String getRealm() { return null; } /** * Returns true. KERBEROS authentication scheme is connection based. * * @return true. */ public boolean isConnectionBased() { return true; } } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/KerberosSchemeFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/KerberosSchemeFactory0100644 0000000 0000000 00000004353 12301751702 032473 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeFactory; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; /** * {@link AuthSchemeProvider} implementation that creates and initializes * {@link KerberosScheme} instances. * * @since 4.2 */ @Immutable @SuppressWarnings("deprecation") public class KerberosSchemeFactory implements AuthSchemeFactory, AuthSchemeProvider { private final boolean stripPort; public KerberosSchemeFactory(final boolean stripPort) { super(); this.stripPort = stripPort; } public KerberosSchemeFactory() { this(false); } public boolean isStripPort() { return stripPort; } public AuthScheme newInstance(final HttpParams params) { return new KerberosScheme(this.stripPort); } public AuthScheme create(final HttpContext context) { return new KerberosScheme(this.stripPort); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/NTLMEngine.java0100644 0000000 0000000 00000004647 12301751702 031070 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; /** * Abstract NTLM authentication engine. The engine can be used to * generate Type1 messages and Type3 messages in response to a * Type2 challenge. * * @since 4.0 */ public interface NTLMEngine { /** * Generates a Type1 message given the domain and workstation. * * @param domain Optional Windows domain name. Can be null. * @param workstation Optional Windows workstation name. Can be * null. * @return Type1 message * @throws NTLMEngineException */ String generateType1Msg( String domain, String workstation) throws NTLMEngineException; /** * Generates a Type3 message given the user credentials and the * authentication challenge. * * @param username Windows user name * @param password Password * @param domain Windows domain name * @param workstation Windows workstation name * @param challenge Type2 challenge. * @return Type3 response. * @throws NTLMEngineException */ String generateType3Msg( String username, String password, String domain, String workstation, String challenge) throws NTLMEngineException; } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/NTLMEngineException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/NTLMEngineException.j0100644 0000000 0000000 00000004323 12301751702 032246 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthenticationException; /** * Signals NTLM protocol failure. * * * @since 4.0 */ @Immutable public class NTLMEngineException extends AuthenticationException { private static final long serialVersionUID = 6027981323731768824L; public NTLMEngineException() { super(); } /** * Creates a new NTLMEngineException with the specified message. * * @param message the exception detail message */ public NTLMEngineException(final String message) { super(message); } /** * Creates a new NTLMEngineException with the specified detail message and cause. * * @param message the exception detail message * @param cause the Throwable that caused this exception, or null * if the cause is unavailable, unknown, or not a Throwable */ public NTLMEngineException(final String message, final Throwable cause) { super(message, cause); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/NTLMEngineImpl.java0100644 0000000 0000000 00000202600 12301751702 031677 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import java.io.UnsupportedEncodingException; import java.security.Key; import java.security.MessageDigest; import java.util.Arrays; import java.util.Locale; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.util.EncodingUtils; /** * Provides an implementation for NTLMv1, NTLMv2, and NTLM2 Session forms of the NTLM * authentication protocol. * * @since 4.1 */ @NotThreadSafe final class NTLMEngineImpl implements NTLMEngine { // Flags we use; descriptions according to: // http://davenport.sourceforge.net/ntlm.html // and // http://msdn.microsoft.com/en-us/library/cc236650%28v=prot.20%29.aspx protected static final int FLAG_REQUEST_UNICODE_ENCODING = 0x00000001; // Unicode string encoding requested protected static final int FLAG_REQUEST_TARGET = 0x00000004; // Requests target field protected static final int FLAG_REQUEST_SIGN = 0x00000010; // Requests all messages have a signature attached, in NEGOTIATE message. protected static final int FLAG_REQUEST_SEAL = 0x00000020; // Request key exchange for message confidentiality in NEGOTIATE message. MUST be used in conjunction with 56BIT. protected static final int FLAG_REQUEST_LAN_MANAGER_KEY = 0x00000080; // Request Lan Manager key instead of user session key protected static final int FLAG_REQUEST_NTLMv1 = 0x00000200; // Request NTLMv1 security. MUST be set in NEGOTIATE and CHALLENGE both protected static final int FLAG_DOMAIN_PRESENT = 0x00001000; // Domain is present in message protected static final int FLAG_WORKSTATION_PRESENT = 0x00002000; // Workstation is present in message protected static final int FLAG_REQUEST_ALWAYS_SIGN = 0x00008000; // Requests a signature block on all messages. Overridden by REQUEST_SIGN and REQUEST_SEAL. protected static final int FLAG_REQUEST_NTLM2_SESSION = 0x00080000; // From server in challenge, requesting NTLM2 session security protected static final int FLAG_REQUEST_VERSION = 0x02000000; // Request protocol version protected static final int FLAG_TARGETINFO_PRESENT = 0x00800000; // From server in challenge message, indicating targetinfo is present protected static final int FLAG_REQUEST_128BIT_KEY_EXCH = 0x20000000; // Request explicit 128-bit key exchange protected static final int FLAG_REQUEST_EXPLICIT_KEY_EXCH = 0x40000000; // Request explicit key exchange protected static final int FLAG_REQUEST_56BIT_ENCRYPTION = 0x80000000; // Must be used in conjunction with SEAL /** Secure random generator */ private static final java.security.SecureRandom RND_GEN; static { java.security.SecureRandom rnd = null; try { rnd = java.security.SecureRandom.getInstance("SHA1PRNG"); } catch (final Exception ignore) { } RND_GEN = rnd; } /** Character encoding */ static final String DEFAULT_CHARSET = "ASCII"; /** The character set to use for encoding the credentials */ private String credentialCharset = DEFAULT_CHARSET; /** The signature string as bytes in the default encoding */ private static final byte[] SIGNATURE; static { final byte[] bytesWithoutNull = EncodingUtils.getBytes("NTLMSSP", "ASCII"); SIGNATURE = new byte[bytesWithoutNull.length + 1]; System.arraycopy(bytesWithoutNull, 0, SIGNATURE, 0, bytesWithoutNull.length); SIGNATURE[bytesWithoutNull.length] = (byte) 0x00; } /** * Returns the response for the given message. * * @param message * the message that was received from the server. * @param username * the username to authenticate with. * @param password * the password to authenticate with. * @param host * The host. * @param domain * the NT domain to authenticate in. * @return The response. * @throws org.apache.http.HttpException * If the messages cannot be retrieved. */ final String getResponseFor(final String message, final String username, final String password, final String host, final String domain) throws NTLMEngineException { final String response; if (message == null || message.trim().equals("")) { response = getType1Message(host, domain); } else { final Type2Message t2m = new Type2Message(message); response = getType3Message(username, password, host, domain, t2m.getChallenge(), t2m .getFlags(), t2m.getTarget(), t2m.getTargetInfo()); } return response; } /** * Creates the first message (type 1 message) in the NTLM authentication * sequence. This message includes the user name, domain and host for the * authentication session. * * @param host * the computer name of the host requesting authentication. * @param domain * The domain to authenticate with. * @return String the message to add to the HTTP request header. */ String getType1Message(final String host, final String domain) throws NTLMEngineException { return new Type1Message(domain, host).getResponse(); } /** * Creates the type 3 message using the given server nonce. The type 3 * message includes all the information for authentication, host, domain, * username and the result of encrypting the nonce sent by the server using * the user's password as the key. * * @param user * The user name. This should not include the domain name. * @param password * The password. * @param host * The host that is originating the authentication request. * @param domain * The domain to authenticate within. * @param nonce * the 8 byte array the server sent. * @return The type 3 message. * @throws NTLMEngineException * If {@encrypt(byte[],byte[])} fails. */ String getType3Message(final String user, final String password, final String host, final String domain, final byte[] nonce, final int type2Flags, final String target, final byte[] targetInformation) throws NTLMEngineException { return new Type3Message(domain, host, user, password, nonce, type2Flags, target, targetInformation).getResponse(); } /** * @return Returns the credentialCharset. */ String getCredentialCharset() { return credentialCharset; } /** * @param credentialCharset * The credentialCharset to set. */ void setCredentialCharset(final String credentialCharset) { this.credentialCharset = credentialCharset; } /** Strip dot suffix from a name */ private static String stripDotSuffix(final String value) { if (value == null) { return null; } final int index = value.indexOf("."); if (index != -1) { return value.substring(0, index); } return value; } /** Convert host to standard form */ private static String convertHost(final String host) { return stripDotSuffix(host); } /** Convert domain to standard form */ private static String convertDomain(final String domain) { return stripDotSuffix(domain); } private static int readULong(final byte[] src, final int index) throws NTLMEngineException { if (src.length < index + 4) { throw new NTLMEngineException("NTLM authentication - buffer too small for DWORD"); } return (src[index] & 0xff) | ((src[index + 1] & 0xff) << 8) | ((src[index + 2] & 0xff) << 16) | ((src[index + 3] & 0xff) << 24); } private static int readUShort(final byte[] src, final int index) throws NTLMEngineException { if (src.length < index + 2) { throw new NTLMEngineException("NTLM authentication - buffer too small for WORD"); } return (src[index] & 0xff) | ((src[index + 1] & 0xff) << 8); } private static byte[] readSecurityBuffer(final byte[] src, final int index) throws NTLMEngineException { final int length = readUShort(src, index); final int offset = readULong(src, index + 4); if (src.length < offset + length) { throw new NTLMEngineException( "NTLM authentication - buffer too small for data item"); } final byte[] buffer = new byte[length]; System.arraycopy(src, offset, buffer, 0, length); return buffer; } /** Calculate a challenge block */ private static byte[] makeRandomChallenge() throws NTLMEngineException { if (RND_GEN == null) { throw new NTLMEngineException("Random generator not available"); } final byte[] rval = new byte[8]; synchronized (RND_GEN) { RND_GEN.nextBytes(rval); } return rval; } /** Calculate a 16-byte secondary key */ private static byte[] makeSecondaryKey() throws NTLMEngineException { if (RND_GEN == null) { throw new NTLMEngineException("Random generator not available"); } final byte[] rval = new byte[16]; synchronized (RND_GEN) { RND_GEN.nextBytes(rval); } return rval; } protected static class CipherGen { protected final String domain; protected final String user; protected final String password; protected final byte[] challenge; protected final String target; protected final byte[] targetInformation; // Information we can generate but may be passed in (for testing) protected byte[] clientChallenge; protected byte[] clientChallenge2; protected byte[] secondaryKey; protected byte[] timestamp; // Stuff we always generate protected byte[] lmHash = null; protected byte[] lmResponse = null; protected byte[] ntlmHash = null; protected byte[] ntlmResponse = null; protected byte[] ntlmv2Hash = null; protected byte[] lmv2Hash = null; protected byte[] lmv2Response = null; protected byte[] ntlmv2Blob = null; protected byte[] ntlmv2Response = null; protected byte[] ntlm2SessionResponse = null; protected byte[] lm2SessionResponse = null; protected byte[] lmUserSessionKey = null; protected byte[] ntlmUserSessionKey = null; protected byte[] ntlmv2UserSessionKey = null; protected byte[] ntlm2SessionResponseUserSessionKey = null; protected byte[] lanManagerSessionKey = null; public CipherGen(final String domain, final String user, final String password, final byte[] challenge, final String target, final byte[] targetInformation, final byte[] clientChallenge, final byte[] clientChallenge2, final byte[] secondaryKey, final byte[] timestamp) { this.domain = domain; this.target = target; this.user = user; this.password = password; this.challenge = challenge; this.targetInformation = targetInformation; this.clientChallenge = clientChallenge; this.clientChallenge2 = clientChallenge2; this.secondaryKey = secondaryKey; this.timestamp = timestamp; } public CipherGen(final String domain, final String user, final String password, final byte[] challenge, final String target, final byte[] targetInformation) { this(domain, user, password, challenge, target, targetInformation, null, null, null, null); } /** Calculate and return client challenge */ public byte[] getClientChallenge() throws NTLMEngineException { if (clientChallenge == null) { clientChallenge = makeRandomChallenge(); } return clientChallenge; } /** Calculate and return second client challenge */ public byte[] getClientChallenge2() throws NTLMEngineException { if (clientChallenge2 == null) { clientChallenge2 = makeRandomChallenge(); } return clientChallenge2; } /** Calculate and return random secondary key */ public byte[] getSecondaryKey() throws NTLMEngineException { if (secondaryKey == null) { secondaryKey = makeSecondaryKey(); } return secondaryKey; } /** Calculate and return the LMHash */ public byte[] getLMHash() throws NTLMEngineException { if (lmHash == null) { lmHash = lmHash(password); } return lmHash; } /** Calculate and return the LMResponse */ public byte[] getLMResponse() throws NTLMEngineException { if (lmResponse == null) { lmResponse = lmResponse(getLMHash(),challenge); } return lmResponse; } /** Calculate and return the NTLMHash */ public byte[] getNTLMHash() throws NTLMEngineException { if (ntlmHash == null) { ntlmHash = ntlmHash(password); } return ntlmHash; } /** Calculate and return the NTLMResponse */ public byte[] getNTLMResponse() throws NTLMEngineException { if (ntlmResponse == null) { ntlmResponse = lmResponse(getNTLMHash(),challenge); } return ntlmResponse; } /** Calculate the LMv2 hash */ public byte[] getLMv2Hash() throws NTLMEngineException { if (lmv2Hash == null) { lmv2Hash = lmv2Hash(domain, user, getNTLMHash()); } return lmv2Hash; } /** Calculate the NTLMv2 hash */ public byte[] getNTLMv2Hash() throws NTLMEngineException { if (ntlmv2Hash == null) { ntlmv2Hash = ntlmv2Hash(domain, user, getNTLMHash()); } return ntlmv2Hash; } /** Calculate a timestamp */ public byte[] getTimestamp() { if (timestamp == null) { long time = System.currentTimeMillis(); time += 11644473600000l; // milliseconds from January 1, 1601 -> epoch. time *= 10000; // tenths of a microsecond. // convert to little-endian byte array. timestamp = new byte[8]; for (int i = 0; i < 8; i++) { timestamp[i] = (byte) time; time >>>= 8; } } return timestamp; } /** Calculate the NTLMv2Blob */ public byte[] getNTLMv2Blob() throws NTLMEngineException { if (ntlmv2Blob == null) { ntlmv2Blob = createBlob(getClientChallenge2(), targetInformation, getTimestamp()); } return ntlmv2Blob; } /** Calculate the NTLMv2Response */ public byte[] getNTLMv2Response() throws NTLMEngineException { if (ntlmv2Response == null) { ntlmv2Response = lmv2Response(getNTLMv2Hash(),challenge,getNTLMv2Blob()); } return ntlmv2Response; } /** Calculate the LMv2Response */ public byte[] getLMv2Response() throws NTLMEngineException { if (lmv2Response == null) { lmv2Response = lmv2Response(getLMv2Hash(),challenge,getClientChallenge()); } return lmv2Response; } /** Get NTLM2SessionResponse */ public byte[] getNTLM2SessionResponse() throws NTLMEngineException { if (ntlm2SessionResponse == null) { ntlm2SessionResponse = ntlm2SessionResponse(getNTLMHash(),challenge,getClientChallenge()); } return ntlm2SessionResponse; } /** Calculate and return LM2 session response */ public byte[] getLM2SessionResponse() throws NTLMEngineException { if (lm2SessionResponse == null) { final byte[] clientChallenge = getClientChallenge(); lm2SessionResponse = new byte[24]; System.arraycopy(clientChallenge, 0, lm2SessionResponse, 0, clientChallenge.length); Arrays.fill(lm2SessionResponse, clientChallenge.length, lm2SessionResponse.length, (byte) 0x00); } return lm2SessionResponse; } /** Get LMUserSessionKey */ public byte[] getLMUserSessionKey() throws NTLMEngineException { if (lmUserSessionKey == null) { final byte[] lmHash = getLMHash(); lmUserSessionKey = new byte[16]; System.arraycopy(lmHash, 0, lmUserSessionKey, 0, 8); Arrays.fill(lmUserSessionKey, 8, 16, (byte) 0x00); } return lmUserSessionKey; } /** Get NTLMUserSessionKey */ public byte[] getNTLMUserSessionKey() throws NTLMEngineException { if (ntlmUserSessionKey == null) { final byte[] ntlmHash = getNTLMHash(); final MD4 md4 = new MD4(); md4.update(ntlmHash); ntlmUserSessionKey = md4.getOutput(); } return ntlmUserSessionKey; } /** GetNTLMv2UserSessionKey */ public byte[] getNTLMv2UserSessionKey() throws NTLMEngineException { if (ntlmv2UserSessionKey == null) { final byte[] ntlmv2hash = getNTLMv2Hash(); final byte[] truncatedResponse = new byte[16]; System.arraycopy(getNTLMv2Response(), 0, truncatedResponse, 0, 16); ntlmv2UserSessionKey = hmacMD5(truncatedResponse, ntlmv2hash); } return ntlmv2UserSessionKey; } /** Get NTLM2SessionResponseUserSessionKey */ public byte[] getNTLM2SessionResponseUserSessionKey() throws NTLMEngineException { if (ntlm2SessionResponseUserSessionKey == null) { final byte[] ntlmUserSessionKey = getNTLMUserSessionKey(); final byte[] ntlm2SessionResponseNonce = getLM2SessionResponse(); final byte[] sessionNonce = new byte[challenge.length + ntlm2SessionResponseNonce.length]; System.arraycopy(challenge, 0, sessionNonce, 0, challenge.length); System.arraycopy(ntlm2SessionResponseNonce, 0, sessionNonce, challenge.length, ntlm2SessionResponseNonce.length); ntlm2SessionResponseUserSessionKey = hmacMD5(sessionNonce,ntlmUserSessionKey); } return ntlm2SessionResponseUserSessionKey; } /** Get LAN Manager session key */ public byte[] getLanManagerSessionKey() throws NTLMEngineException { if (lanManagerSessionKey == null) { final byte[] lmHash = getLMHash(); final byte[] lmResponse = getLMResponse(); try { final byte[] keyBytes = new byte[14]; System.arraycopy(lmHash, 0, keyBytes, 0, 8); Arrays.fill(keyBytes, 8, keyBytes.length, (byte)0xbd); final Key lowKey = createDESKey(keyBytes, 0); final Key highKey = createDESKey(keyBytes, 7); final byte[] truncatedResponse = new byte[8]; System.arraycopy(lmResponse, 0, truncatedResponse, 0, truncatedResponse.length); Cipher des = Cipher.getInstance("DES/ECB/NoPadding"); des.init(Cipher.ENCRYPT_MODE, lowKey); final byte[] lowPart = des.doFinal(truncatedResponse); des = Cipher.getInstance("DES/ECB/NoPadding"); des.init(Cipher.ENCRYPT_MODE, highKey); final byte[] highPart = des.doFinal(truncatedResponse); lanManagerSessionKey = new byte[16]; System.arraycopy(lowPart, 0, lanManagerSessionKey, 0, lowPart.length); System.arraycopy(highPart, 0, lanManagerSessionKey, lowPart.length, highPart.length); } catch (final Exception e) { throw new NTLMEngineException(e.getMessage(), e); } } return lanManagerSessionKey; } } /** Calculates HMAC-MD5 */ static byte[] hmacMD5(final byte[] value, final byte[] key) throws NTLMEngineException { final HMACMD5 hmacMD5 = new HMACMD5(key); hmacMD5.update(value); return hmacMD5.getOutput(); } /** Calculates RC4 */ static byte[] RC4(final byte[] value, final byte[] key) throws NTLMEngineException { try { final Cipher rc4 = Cipher.getInstance("RC4"); rc4.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "RC4")); return rc4.doFinal(value); } catch (final Exception e) { throw new NTLMEngineException(e.getMessage(), e); } } /** * Calculates the NTLM2 Session Response for the given challenge, using the * specified password and client challenge. * * @return The NTLM2 Session Response. This is placed in the NTLM response * field of the Type 3 message; the LM response field contains the * client challenge, null-padded to 24 bytes. */ static byte[] ntlm2SessionResponse(final byte[] ntlmHash, final byte[] challenge, final byte[] clientChallenge) throws NTLMEngineException { try { // Look up MD5 algorithm (was necessary on jdk 1.4.2) // This used to be needed, but java 1.5.0_07 includes the MD5 // algorithm (finally) // Class x = Class.forName("gnu.crypto.hash.MD5"); // Method updateMethod = x.getMethod("update",new // Class[]{byte[].class}); // Method digestMethod = x.getMethod("digest",new Class[0]); // Object mdInstance = x.newInstance(); // updateMethod.invoke(mdInstance,new Object[]{challenge}); // updateMethod.invoke(mdInstance,new Object[]{clientChallenge}); // byte[] digest = (byte[])digestMethod.invoke(mdInstance,new // Object[0]); final MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(challenge); md5.update(clientChallenge); final byte[] digest = md5.digest(); final byte[] sessionHash = new byte[8]; System.arraycopy(digest, 0, sessionHash, 0, 8); return lmResponse(ntlmHash, sessionHash); } catch (final Exception e) { if (e instanceof NTLMEngineException) { throw (NTLMEngineException) e; } throw new NTLMEngineException(e.getMessage(), e); } } /** * Creates the LM Hash of the user's password. * * @param password * The password. * * @return The LM Hash of the given password, used in the calculation of the * LM Response. */ private static byte[] lmHash(final String password) throws NTLMEngineException { try { final byte[] oemPassword = password.toUpperCase(Locale.US).getBytes("US-ASCII"); final int length = Math.min(oemPassword.length, 14); final byte[] keyBytes = new byte[14]; System.arraycopy(oemPassword, 0, keyBytes, 0, length); final Key lowKey = createDESKey(keyBytes, 0); final Key highKey = createDESKey(keyBytes, 7); final byte[] magicConstant = "KGS!@#$%".getBytes("US-ASCII"); final Cipher des = Cipher.getInstance("DES/ECB/NoPadding"); des.init(Cipher.ENCRYPT_MODE, lowKey); final byte[] lowHash = des.doFinal(magicConstant); des.init(Cipher.ENCRYPT_MODE, highKey); final byte[] highHash = des.doFinal(magicConstant); final byte[] lmHash = new byte[16]; System.arraycopy(lowHash, 0, lmHash, 0, 8); System.arraycopy(highHash, 0, lmHash, 8, 8); return lmHash; } catch (final Exception e) { throw new NTLMEngineException(e.getMessage(), e); } } /** * Creates the NTLM Hash of the user's password. * * @param password * The password. * * @return The NTLM Hash of the given password, used in the calculation of * the NTLM Response and the NTLMv2 and LMv2 Hashes. */ private static byte[] ntlmHash(final String password) throws NTLMEngineException { try { final byte[] unicodePassword = password.getBytes("UnicodeLittleUnmarked"); final MD4 md4 = new MD4(); md4.update(unicodePassword); return md4.getOutput(); } catch (final UnsupportedEncodingException e) { throw new NTLMEngineException("Unicode not supported: " + e.getMessage(), e); } } /** * Creates the LMv2 Hash of the user's password. * * @return The LMv2 Hash, used in the calculation of the NTLMv2 and LMv2 * Responses. */ private static byte[] lmv2Hash(final String domain, final String user, final byte[] ntlmHash) throws NTLMEngineException { try { final HMACMD5 hmacMD5 = new HMACMD5(ntlmHash); // Upper case username, upper case domain! hmacMD5.update(user.toUpperCase(Locale.US).getBytes("UnicodeLittleUnmarked")); if (domain != null) { hmacMD5.update(domain.toUpperCase(Locale.US).getBytes("UnicodeLittleUnmarked")); } return hmacMD5.getOutput(); } catch (final UnsupportedEncodingException e) { throw new NTLMEngineException("Unicode not supported! " + e.getMessage(), e); } } /** * Creates the NTLMv2 Hash of the user's password. * * @return The NTLMv2 Hash, used in the calculation of the NTLMv2 and LMv2 * Responses. */ private static byte[] ntlmv2Hash(final String domain, final String user, final byte[] ntlmHash) throws NTLMEngineException { try { final HMACMD5 hmacMD5 = new HMACMD5(ntlmHash); // Upper case username, mixed case target!! hmacMD5.update(user.toUpperCase(Locale.US).getBytes("UnicodeLittleUnmarked")); if (domain != null) { hmacMD5.update(domain.getBytes("UnicodeLittleUnmarked")); } return hmacMD5.getOutput(); } catch (final UnsupportedEncodingException e) { throw new NTLMEngineException("Unicode not supported! " + e.getMessage(), e); } } /** * Creates the LM Response from the given hash and Type 2 challenge. * * @param hash * The LM or NTLM Hash. * @param challenge * The server challenge from the Type 2 message. * * @return The response (either LM or NTLM, depending on the provided hash). */ private static byte[] lmResponse(final byte[] hash, final byte[] challenge) throws NTLMEngineException { try { final byte[] keyBytes = new byte[21]; System.arraycopy(hash, 0, keyBytes, 0, 16); final Key lowKey = createDESKey(keyBytes, 0); final Key middleKey = createDESKey(keyBytes, 7); final Key highKey = createDESKey(keyBytes, 14); final Cipher des = Cipher.getInstance("DES/ECB/NoPadding"); des.init(Cipher.ENCRYPT_MODE, lowKey); final byte[] lowResponse = des.doFinal(challenge); des.init(Cipher.ENCRYPT_MODE, middleKey); final byte[] middleResponse = des.doFinal(challenge); des.init(Cipher.ENCRYPT_MODE, highKey); final byte[] highResponse = des.doFinal(challenge); final byte[] lmResponse = new byte[24]; System.arraycopy(lowResponse, 0, lmResponse, 0, 8); System.arraycopy(middleResponse, 0, lmResponse, 8, 8); System.arraycopy(highResponse, 0, lmResponse, 16, 8); return lmResponse; } catch (final Exception e) { throw new NTLMEngineException(e.getMessage(), e); } } /** * Creates the LMv2 Response from the given hash, client data, and Type 2 * challenge. * * @param hash * The NTLMv2 Hash. * @param clientData * The client data (blob or client challenge). * @param challenge * The server challenge from the Type 2 message. * * @return The response (either NTLMv2 or LMv2, depending on the client * data). */ private static byte[] lmv2Response(final byte[] hash, final byte[] challenge, final byte[] clientData) throws NTLMEngineException { final HMACMD5 hmacMD5 = new HMACMD5(hash); hmacMD5.update(challenge); hmacMD5.update(clientData); final byte[] mac = hmacMD5.getOutput(); final byte[] lmv2Response = new byte[mac.length + clientData.length]; System.arraycopy(mac, 0, lmv2Response, 0, mac.length); System.arraycopy(clientData, 0, lmv2Response, mac.length, clientData.length); return lmv2Response; } /** * Creates the NTLMv2 blob from the given target information block and * client challenge. * * @param targetInformation * The target information block from the Type 2 message. * @param clientChallenge * The random 8-byte client challenge. * * @return The blob, used in the calculation of the NTLMv2 Response. */ private static byte[] createBlob(final byte[] clientChallenge, final byte[] targetInformation, final byte[] timestamp) { final byte[] blobSignature = new byte[] { (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00 }; final byte[] reserved = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; final byte[] unknown1 = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; final byte[] unknown2 = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; final byte[] blob = new byte[blobSignature.length + reserved.length + timestamp.length + 8 + unknown1.length + targetInformation.length + unknown2.length]; int offset = 0; System.arraycopy(blobSignature, 0, blob, offset, blobSignature.length); offset += blobSignature.length; System.arraycopy(reserved, 0, blob, offset, reserved.length); offset += reserved.length; System.arraycopy(timestamp, 0, blob, offset, timestamp.length); offset += timestamp.length; System.arraycopy(clientChallenge, 0, blob, offset, 8); offset += 8; System.arraycopy(unknown1, 0, blob, offset, unknown1.length); offset += unknown1.length; System.arraycopy(targetInformation, 0, blob, offset, targetInformation.length); offset += targetInformation.length; System.arraycopy(unknown2, 0, blob, offset, unknown2.length); offset += unknown2.length; return blob; } /** * Creates a DES encryption key from the given key material. * * @param bytes * A byte array containing the DES key material. * @param offset * The offset in the given byte array at which the 7-byte key * material starts. * * @return A DES encryption key created from the key material starting at * the specified offset in the given byte array. */ private static Key createDESKey(final byte[] bytes, final int offset) { final byte[] keyBytes = new byte[7]; System.arraycopy(bytes, offset, keyBytes, 0, 7); final byte[] material = new byte[8]; material[0] = keyBytes[0]; material[1] = (byte) (keyBytes[0] << 7 | (keyBytes[1] & 0xff) >>> 1); material[2] = (byte) (keyBytes[1] << 6 | (keyBytes[2] & 0xff) >>> 2); material[3] = (byte) (keyBytes[2] << 5 | (keyBytes[3] & 0xff) >>> 3); material[4] = (byte) (keyBytes[3] << 4 | (keyBytes[4] & 0xff) >>> 4); material[5] = (byte) (keyBytes[4] << 3 | (keyBytes[5] & 0xff) >>> 5); material[6] = (byte) (keyBytes[5] << 2 | (keyBytes[6] & 0xff) >>> 6); material[7] = (byte) (keyBytes[6] << 1); oddParity(material); return new SecretKeySpec(material, "DES"); } /** * Applies odd parity to the given byte array. * * @param bytes * The data whose parity bits are to be adjusted for odd parity. */ private static void oddParity(final byte[] bytes) { for (int i = 0; i < bytes.length; i++) { final byte b = bytes[i]; final boolean needsParity = (((b >>> 7) ^ (b >>> 6) ^ (b >>> 5) ^ (b >>> 4) ^ (b >>> 3) ^ (b >>> 2) ^ (b >>> 1)) & 0x01) == 0; if (needsParity) { bytes[i] |= (byte) 0x01; } else { bytes[i] &= (byte) 0xfe; } } } /** NTLM message generation, base class */ static class NTLMMessage { /** The current response */ private byte[] messageContents = null; /** The current output position */ private int currentOutputPosition = 0; /** Constructor to use when message contents are not yet known */ NTLMMessage() { } /** Constructor to use when message contents are known */ NTLMMessage(final String messageBody, final int expectedType) throws NTLMEngineException { messageContents = Base64.decodeBase64(EncodingUtils.getBytes(messageBody, DEFAULT_CHARSET)); // Look for NTLM message if (messageContents.length < SIGNATURE.length) { throw new NTLMEngineException("NTLM message decoding error - packet too short"); } int i = 0; while (i < SIGNATURE.length) { if (messageContents[i] != SIGNATURE[i]) { throw new NTLMEngineException( "NTLM message expected - instead got unrecognized bytes"); } i++; } // Check to be sure there's a type 2 message indicator next final int type = readULong(SIGNATURE.length); if (type != expectedType) { throw new NTLMEngineException("NTLM type " + Integer.toString(expectedType) + " message expected - instead got type " + Integer.toString(type)); } currentOutputPosition = messageContents.length; } /** * Get the length of the signature and flags, so calculations can adjust * offsets accordingly. */ protected int getPreambleLength() { return SIGNATURE.length + 4; } /** Get the message length */ protected int getMessageLength() { return currentOutputPosition; } /** Read a byte from a position within the message buffer */ protected byte readByte(final int position) throws NTLMEngineException { if (messageContents.length < position + 1) { throw new NTLMEngineException("NTLM: Message too short"); } return messageContents[position]; } /** Read a bunch of bytes from a position in the message buffer */ protected void readBytes(final byte[] buffer, final int position) throws NTLMEngineException { if (messageContents.length < position + buffer.length) { throw new NTLMEngineException("NTLM: Message too short"); } System.arraycopy(messageContents, position, buffer, 0, buffer.length); } /** Read a ushort from a position within the message buffer */ protected int readUShort(final int position) throws NTLMEngineException { return NTLMEngineImpl.readUShort(messageContents, position); } /** Read a ulong from a position within the message buffer */ protected int readULong(final int position) throws NTLMEngineException { return NTLMEngineImpl.readULong(messageContents, position); } /** Read a security buffer from a position within the message buffer */ protected byte[] readSecurityBuffer(final int position) throws NTLMEngineException { return NTLMEngineImpl.readSecurityBuffer(messageContents, position); } /** * Prepares the object to create a response of the given length. * * @param maxlength * the maximum length of the response to prepare, not * including the type and the signature (which this method * adds). */ protected void prepareResponse(final int maxlength, final int messageType) { messageContents = new byte[maxlength]; currentOutputPosition = 0; addBytes(SIGNATURE); addULong(messageType); } /** * Adds the given byte to the response. * * @param b * the byte to add. */ protected void addByte(final byte b) { messageContents[currentOutputPosition] = b; currentOutputPosition++; } /** * Adds the given bytes to the response. * * @param bytes * the bytes to add. */ protected void addBytes(final byte[] bytes) { if (bytes == null) { return; } for (final byte b : bytes) { messageContents[currentOutputPosition] = b; currentOutputPosition++; } } /** Adds a USHORT to the response */ protected void addUShort(final int value) { addByte((byte) (value & 0xff)); addByte((byte) (value >> 8 & 0xff)); } /** Adds a ULong to the response */ protected void addULong(final int value) { addByte((byte) (value & 0xff)); addByte((byte) (value >> 8 & 0xff)); addByte((byte) (value >> 16 & 0xff)); addByte((byte) (value >> 24 & 0xff)); } /** * Returns the response that has been generated after shrinking the * array if required and base64 encodes the response. * * @return The response as above. */ String getResponse() { final byte[] resp; if (messageContents.length > currentOutputPosition) { final byte[] tmp = new byte[currentOutputPosition]; System.arraycopy(messageContents, 0, tmp, 0, currentOutputPosition); resp = tmp; } else { resp = messageContents; } return EncodingUtils.getAsciiString(Base64.encodeBase64(resp)); } } /** Type 1 message assembly class */ static class Type1Message extends NTLMMessage { protected byte[] hostBytes; protected byte[] domainBytes; /** Constructor. Include the arguments the message will need */ Type1Message(final String domain, final String host) throws NTLMEngineException { super(); try { // Strip off domain name from the host! final String unqualifiedHost = convertHost(host); // Use only the base domain name! final String unqualifiedDomain = convertDomain(domain); hostBytes = unqualifiedHost != null? unqualifiedHost.getBytes("ASCII") : null; domainBytes = unqualifiedDomain != null ? unqualifiedDomain .toUpperCase(Locale.US).getBytes("ASCII") : null; } catch (final UnsupportedEncodingException e) { throw new NTLMEngineException("Unicode unsupported: " + e.getMessage(), e); } } /** * Getting the response involves building the message before returning * it */ @Override String getResponse() { // Now, build the message. Calculate its length first, including // signature or type. final int finalLength = 32 + 8 /*+ hostBytes.length + domainBytes.length */; // Set up the response. This will initialize the signature, message // type, and flags. prepareResponse(finalLength, 1); // Flags. These are the complete set of flags we support. addULong( //FLAG_WORKSTATION_PRESENT | //FLAG_DOMAIN_PRESENT | // Required flags //FLAG_REQUEST_LAN_MANAGER_KEY | FLAG_REQUEST_NTLMv1 | FLAG_REQUEST_NTLM2_SESSION | // Protocol version request FLAG_REQUEST_VERSION | // Recommended privacy settings FLAG_REQUEST_ALWAYS_SIGN | //FLAG_REQUEST_SEAL | //FLAG_REQUEST_SIGN | // These must be set according to documentation, based on use of SEAL above FLAG_REQUEST_128BIT_KEY_EXCH | FLAG_REQUEST_56BIT_ENCRYPTION | //FLAG_REQUEST_EXPLICIT_KEY_EXCH | FLAG_REQUEST_UNICODE_ENCODING); // Domain length (two times). addUShort(/*domainBytes.length*/0); addUShort(/*domainBytes.length*/0); // Domain offset. addULong(/*hostBytes.length +*/ 32 + 8); // Host length (two times). addUShort(/*hostBytes.length*/0); addUShort(/*hostBytes.length*/0); // Host offset (always 32 + 8). addULong(32 + 8); // Version addUShort(0x0105); // Build addULong(2600); // NTLM revision addUShort(0x0f00); // Host (workstation) String. //addBytes(hostBytes); // Domain String. //addBytes(domainBytes); return super.getResponse(); } } /** Type 2 message class */ static class Type2Message extends NTLMMessage { protected byte[] challenge; protected String target; protected byte[] targetInfo; protected int flags; Type2Message(final String message) throws NTLMEngineException { super(message, 2); // Type 2 message is laid out as follows: // First 8 bytes: NTLMSSP[0] // Next 4 bytes: Ulong, value 2 // Next 8 bytes, starting at offset 12: target field (2 ushort lengths, 1 ulong offset) // Next 4 bytes, starting at offset 20: Flags, e.g. 0x22890235 // Next 8 bytes, starting at offset 24: Challenge // Next 8 bytes, starting at offset 32: ??? (8 bytes of zeros) // Next 8 bytes, starting at offset 40: targetinfo field (2 ushort lengths, 1 ulong offset) // Next 2 bytes, major/minor version number (e.g. 0x05 0x02) // Next 8 bytes, build number // Next 2 bytes, protocol version number (e.g. 0x00 0x0f) // Next, various text fields, and a ushort of value 0 at the end // Parse out the rest of the info we need from the message // The nonce is the 8 bytes starting from the byte in position 24. challenge = new byte[8]; readBytes(challenge, 24); flags = readULong(20); if ((flags & FLAG_REQUEST_UNICODE_ENCODING) == 0) { throw new NTLMEngineException( "NTLM type 2 message has flags that make no sense: " + Integer.toString(flags)); } // Do the target! target = null; // The TARGET_DESIRED flag is said to not have understood semantics // in Type2 messages, so use the length of the packet to decide // how to proceed instead if (getMessageLength() >= 12 + 8) { final byte[] bytes = readSecurityBuffer(12); if (bytes.length != 0) { try { target = new String(bytes, "UnicodeLittleUnmarked"); } catch (final UnsupportedEncodingException e) { throw new NTLMEngineException(e.getMessage(), e); } } } // Do the target info! targetInfo = null; // TARGET_DESIRED flag cannot be relied on, so use packet length if (getMessageLength() >= 40 + 8) { final byte[] bytes = readSecurityBuffer(40); if (bytes.length != 0) { targetInfo = bytes; } } } /** Retrieve the challenge */ byte[] getChallenge() { return challenge; } /** Retrieve the target */ String getTarget() { return target; } /** Retrieve the target info */ byte[] getTargetInfo() { return targetInfo; } /** Retrieve the response flags */ int getFlags() { return flags; } } /** Type 3 message assembly class */ static class Type3Message extends NTLMMessage { // Response flags from the type2 message protected int type2Flags; protected byte[] domainBytes; protected byte[] hostBytes; protected byte[] userBytes; protected byte[] lmResp; protected byte[] ntResp; protected byte[] sessionKey; /** Constructor. Pass the arguments we will need */ Type3Message(final String domain, final String host, final String user, final String password, final byte[] nonce, final int type2Flags, final String target, final byte[] targetInformation) throws NTLMEngineException { // Save the flags this.type2Flags = type2Flags; // Strip off domain name from the host! final String unqualifiedHost = convertHost(host); // Use only the base domain name! final String unqualifiedDomain = convertDomain(domain); // Create a cipher generator class. Use domain BEFORE it gets modified! final CipherGen gen = new CipherGen(unqualifiedDomain, user, password, nonce, target, targetInformation); // Use the new code to calculate the responses, including v2 if that // seems warranted. byte[] userSessionKey; try { // This conditional may not work on Windows Server 2008 R2 and above, where it has not yet // been tested if (((type2Flags & FLAG_TARGETINFO_PRESENT) != 0) && targetInformation != null && target != null) { // NTLMv2 ntResp = gen.getNTLMv2Response(); lmResp = gen.getLMv2Response(); if ((type2Flags & FLAG_REQUEST_LAN_MANAGER_KEY) != 0) { userSessionKey = gen.getLanManagerSessionKey(); } else { userSessionKey = gen.getNTLMv2UserSessionKey(); } } else { // NTLMv1 if ((type2Flags & FLAG_REQUEST_NTLM2_SESSION) != 0) { // NTLM2 session stuff is requested ntResp = gen.getNTLM2SessionResponse(); lmResp = gen.getLM2SessionResponse(); if ((type2Flags & FLAG_REQUEST_LAN_MANAGER_KEY) != 0) { userSessionKey = gen.getLanManagerSessionKey(); } else { userSessionKey = gen.getNTLM2SessionResponseUserSessionKey(); } } else { ntResp = gen.getNTLMResponse(); lmResp = gen.getLMResponse(); if ((type2Flags & FLAG_REQUEST_LAN_MANAGER_KEY) != 0) { userSessionKey = gen.getLanManagerSessionKey(); } else { userSessionKey = gen.getNTLMUserSessionKey(); } } } } catch (final NTLMEngineException e) { // This likely means we couldn't find the MD4 hash algorithm - // fail back to just using LM ntResp = new byte[0]; lmResp = gen.getLMResponse(); if ((type2Flags & FLAG_REQUEST_LAN_MANAGER_KEY) != 0) { userSessionKey = gen.getLanManagerSessionKey(); } else { userSessionKey = gen.getLMUserSessionKey(); } } if ((type2Flags & FLAG_REQUEST_SIGN) != 0) { if ((type2Flags & FLAG_REQUEST_EXPLICIT_KEY_EXCH) != 0) { sessionKey = RC4(gen.getSecondaryKey(), userSessionKey); } else { sessionKey = userSessionKey; } } else { sessionKey = null; } try { hostBytes = unqualifiedHost != null ? unqualifiedHost .getBytes("UnicodeLittleUnmarked") : null; domainBytes = unqualifiedDomain != null ? unqualifiedDomain .toUpperCase(Locale.US).getBytes("UnicodeLittleUnmarked") : null; userBytes = user.getBytes("UnicodeLittleUnmarked"); } catch (final UnsupportedEncodingException e) { throw new NTLMEngineException("Unicode not supported: " + e.getMessage(), e); } } /** Assemble the response */ @Override String getResponse() { final int ntRespLen = ntResp.length; final int lmRespLen = lmResp.length; final int domainLen = domainBytes != null ? domainBytes.length : 0; final int hostLen = hostBytes != null ? hostBytes.length: 0; final int userLen = userBytes.length; final int sessionKeyLen; if (sessionKey != null) { sessionKeyLen = sessionKey.length; } else { sessionKeyLen = 0; } // Calculate the layout within the packet final int lmRespOffset = 72; // allocate space for the version final int ntRespOffset = lmRespOffset + lmRespLen; final int domainOffset = ntRespOffset + ntRespLen; final int userOffset = domainOffset + domainLen; final int hostOffset = userOffset + userLen; final int sessionKeyOffset = hostOffset + hostLen; final int finalLength = sessionKeyOffset + sessionKeyLen; // Start the response. Length includes signature and type prepareResponse(finalLength, 3); // LM Resp Length (twice) addUShort(lmRespLen); addUShort(lmRespLen); // LM Resp Offset addULong(lmRespOffset); // NT Resp Length (twice) addUShort(ntRespLen); addUShort(ntRespLen); // NT Resp Offset addULong(ntRespOffset); // Domain length (twice) addUShort(domainLen); addUShort(domainLen); // Domain offset. addULong(domainOffset); // User Length (twice) addUShort(userLen); addUShort(userLen); // User offset addULong(userOffset); // Host length (twice) addUShort(hostLen); addUShort(hostLen); // Host offset addULong(hostOffset); // Session key length (twice) addUShort(sessionKeyLen); addUShort(sessionKeyLen); // Session key offset addULong(sessionKeyOffset); // Flags. addULong( //FLAG_WORKSTATION_PRESENT | //FLAG_DOMAIN_PRESENT | // Required flags (type2Flags & FLAG_REQUEST_LAN_MANAGER_KEY) | (type2Flags & FLAG_REQUEST_NTLMv1) | (type2Flags & FLAG_REQUEST_NTLM2_SESSION) | // Protocol version request FLAG_REQUEST_VERSION | // Recommended privacy settings (type2Flags & FLAG_REQUEST_ALWAYS_SIGN) | (type2Flags & FLAG_REQUEST_SEAL) | (type2Flags & FLAG_REQUEST_SIGN) | // These must be set according to documentation, based on use of SEAL above (type2Flags & FLAG_REQUEST_128BIT_KEY_EXCH) | (type2Flags & FLAG_REQUEST_56BIT_ENCRYPTION) | (type2Flags & FLAG_REQUEST_EXPLICIT_KEY_EXCH) | (type2Flags & FLAG_TARGETINFO_PRESENT) | (type2Flags & FLAG_REQUEST_UNICODE_ENCODING) | (type2Flags & FLAG_REQUEST_TARGET) ); // Version addUShort(0x0105); // Build addULong(2600); // NTLM revision addUShort(0x0f00); // Add the actual data addBytes(lmResp); addBytes(ntResp); addBytes(domainBytes); addBytes(userBytes); addBytes(hostBytes); if (sessionKey != null) { addBytes(sessionKey); } return super.getResponse(); } } static void writeULong(final byte[] buffer, final int value, final int offset) { buffer[offset] = (byte) (value & 0xff); buffer[offset + 1] = (byte) (value >> 8 & 0xff); buffer[offset + 2] = (byte) (value >> 16 & 0xff); buffer[offset + 3] = (byte) (value >> 24 & 0xff); } static int F(final int x, final int y, final int z) { return ((x & y) | (~x & z)); } static int G(final int x, final int y, final int z) { return ((x & y) | (x & z) | (y & z)); } static int H(final int x, final int y, final int z) { return (x ^ y ^ z); } static int rotintlft(final int val, final int numbits) { return ((val << numbits) | (val >>> (32 - numbits))); } /** * Cryptography support - MD4. The following class was based loosely on the * RFC and on code found at http://www.cs.umd.edu/~harry/jotp/src/md.java. * Code correctness was verified by looking at MD4.java from the jcifs * library (http://jcifs.samba.org). It was massaged extensively to the * final form found here by Karl Wright (kwright@metacarta.com). */ static class MD4 { protected int A = 0x67452301; protected int B = 0xefcdab89; protected int C = 0x98badcfe; protected int D = 0x10325476; protected long count = 0L; protected byte[] dataBuffer = new byte[64]; MD4() { } void update(final byte[] input) { // We always deal with 512 bits at a time. Correspondingly, there is // a buffer 64 bytes long that we write data into until it gets // full. int curBufferPos = (int) (count & 63L); int inputIndex = 0; while (input.length - inputIndex + curBufferPos >= dataBuffer.length) { // We have enough data to do the next step. Do a partial copy // and a transform, updating inputIndex and curBufferPos // accordingly final int transferAmt = dataBuffer.length - curBufferPos; System.arraycopy(input, inputIndex, dataBuffer, curBufferPos, transferAmt); count += transferAmt; curBufferPos = 0; inputIndex += transferAmt; processBuffer(); } // If there's anything left, copy it into the buffer and leave it. // We know there's not enough left to process. if (inputIndex < input.length) { final int transferAmt = input.length - inputIndex; System.arraycopy(input, inputIndex, dataBuffer, curBufferPos, transferAmt); count += transferAmt; curBufferPos += transferAmt; } } byte[] getOutput() { // Feed pad/length data into engine. This must round out the input // to a multiple of 512 bits. final int bufferIndex = (int) (count & 63L); final int padLen = (bufferIndex < 56) ? (56 - bufferIndex) : (120 - bufferIndex); final byte[] postBytes = new byte[padLen + 8]; // Leading 0x80, specified amount of zero padding, then length in // bits. postBytes[0] = (byte) 0x80; // Fill out the last 8 bytes with the length for (int i = 0; i < 8; i++) { postBytes[padLen + i] = (byte) ((count * 8) >>> (8 * i)); } // Update the engine update(postBytes); // Calculate final result final byte[] result = new byte[16]; writeULong(result, A, 0); writeULong(result, B, 4); writeULong(result, C, 8); writeULong(result, D, 12); return result; } protected void processBuffer() { // Convert current buffer to 16 ulongs final int[] d = new int[16]; for (int i = 0; i < 16; i++) { d[i] = (dataBuffer[i * 4] & 0xff) + ((dataBuffer[i * 4 + 1] & 0xff) << 8) + ((dataBuffer[i * 4 + 2] & 0xff) << 16) + ((dataBuffer[i * 4 + 3] & 0xff) << 24); } // Do a round of processing final int AA = A; final int BB = B; final int CC = C; final int DD = D; round1(d); round2(d); round3(d); A += AA; B += BB; C += CC; D += DD; } protected void round1(final int[] d) { A = rotintlft((A + F(B, C, D) + d[0]), 3); D = rotintlft((D + F(A, B, C) + d[1]), 7); C = rotintlft((C + F(D, A, B) + d[2]), 11); B = rotintlft((B + F(C, D, A) + d[3]), 19); A = rotintlft((A + F(B, C, D) + d[4]), 3); D = rotintlft((D + F(A, B, C) + d[5]), 7); C = rotintlft((C + F(D, A, B) + d[6]), 11); B = rotintlft((B + F(C, D, A) + d[7]), 19); A = rotintlft((A + F(B, C, D) + d[8]), 3); D = rotintlft((D + F(A, B, C) + d[9]), 7); C = rotintlft((C + F(D, A, B) + d[10]), 11); B = rotintlft((B + F(C, D, A) + d[11]), 19); A = rotintlft((A + F(B, C, D) + d[12]), 3); D = rotintlft((D + F(A, B, C) + d[13]), 7); C = rotintlft((C + F(D, A, B) + d[14]), 11); B = rotintlft((B + F(C, D, A) + d[15]), 19); } protected void round2(final int[] d) { A = rotintlft((A + G(B, C, D) + d[0] + 0x5a827999), 3); D = rotintlft((D + G(A, B, C) + d[4] + 0x5a827999), 5); C = rotintlft((C + G(D, A, B) + d[8] + 0x5a827999), 9); B = rotintlft((B + G(C, D, A) + d[12] + 0x5a827999), 13); A = rotintlft((A + G(B, C, D) + d[1] + 0x5a827999), 3); D = rotintlft((D + G(A, B, C) + d[5] + 0x5a827999), 5); C = rotintlft((C + G(D, A, B) + d[9] + 0x5a827999), 9); B = rotintlft((B + G(C, D, A) + d[13] + 0x5a827999), 13); A = rotintlft((A + G(B, C, D) + d[2] + 0x5a827999), 3); D = rotintlft((D + G(A, B, C) + d[6] + 0x5a827999), 5); C = rotintlft((C + G(D, A, B) + d[10] + 0x5a827999), 9); B = rotintlft((B + G(C, D, A) + d[14] + 0x5a827999), 13); A = rotintlft((A + G(B, C, D) + d[3] + 0x5a827999), 3); D = rotintlft((D + G(A, B, C) + d[7] + 0x5a827999), 5); C = rotintlft((C + G(D, A, B) + d[11] + 0x5a827999), 9); B = rotintlft((B + G(C, D, A) + d[15] + 0x5a827999), 13); } protected void round3(final int[] d) { A = rotintlft((A + H(B, C, D) + d[0] + 0x6ed9eba1), 3); D = rotintlft((D + H(A, B, C) + d[8] + 0x6ed9eba1), 9); C = rotintlft((C + H(D, A, B) + d[4] + 0x6ed9eba1), 11); B = rotintlft((B + H(C, D, A) + d[12] + 0x6ed9eba1), 15); A = rotintlft((A + H(B, C, D) + d[2] + 0x6ed9eba1), 3); D = rotintlft((D + H(A, B, C) + d[10] + 0x6ed9eba1), 9); C = rotintlft((C + H(D, A, B) + d[6] + 0x6ed9eba1), 11); B = rotintlft((B + H(C, D, A) + d[14] + 0x6ed9eba1), 15); A = rotintlft((A + H(B, C, D) + d[1] + 0x6ed9eba1), 3); D = rotintlft((D + H(A, B, C) + d[9] + 0x6ed9eba1), 9); C = rotintlft((C + H(D, A, B) + d[5] + 0x6ed9eba1), 11); B = rotintlft((B + H(C, D, A) + d[13] + 0x6ed9eba1), 15); A = rotintlft((A + H(B, C, D) + d[3] + 0x6ed9eba1), 3); D = rotintlft((D + H(A, B, C) + d[11] + 0x6ed9eba1), 9); C = rotintlft((C + H(D, A, B) + d[7] + 0x6ed9eba1), 11); B = rotintlft((B + H(C, D, A) + d[15] + 0x6ed9eba1), 15); } } /** * Cryptography support - HMACMD5 - algorithmically based on various web * resources by Karl Wright */ static class HMACMD5 { protected byte[] ipad; protected byte[] opad; protected MessageDigest md5; HMACMD5(final byte[] input) throws NTLMEngineException { byte[] key = input; try { md5 = MessageDigest.getInstance("MD5"); } catch (final Exception ex) { // Umm, the algorithm doesn't exist - throw an // NTLMEngineException! throw new NTLMEngineException( "Error getting md5 message digest implementation: " + ex.getMessage(), ex); } // Initialize the pad buffers with the key ipad = new byte[64]; opad = new byte[64]; int keyLength = key.length; if (keyLength > 64) { // Use MD5 of the key instead, as described in RFC 2104 md5.update(key); key = md5.digest(); keyLength = key.length; } int i = 0; while (i < keyLength) { ipad[i] = (byte) (key[i] ^ (byte) 0x36); opad[i] = (byte) (key[i] ^ (byte) 0x5c); i++; } while (i < 64) { ipad[i] = (byte) 0x36; opad[i] = (byte) 0x5c; i++; } // Very important: update the digest with the ipad buffer md5.reset(); md5.update(ipad); } /** Grab the current digest. This is the "answer". */ byte[] getOutput() { final byte[] digest = md5.digest(); md5.update(opad); return md5.digest(digest); } /** Update by adding a complete array */ void update(final byte[] input) { md5.update(input); } /** Update the algorithm */ void update(final byte[] input, final int offset, final int length) { md5.update(input, offset, length); } } public String generateType1Msg( final String domain, final String workstation) throws NTLMEngineException { return getType1Message(workstation, domain); } public String generateType3Msg( final String username, final String password, final String domain, final String workstation, final String challenge) throws NTLMEngineException { final Type2Message t2m = new Type2Message(challenge); return getType3Message( username, password, workstation, domain, t2m.getChallenge(), t2m.getFlags(), t2m.getTarget(), t2m.getTargetInfo()); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/NTLMScheme.java0100644 0000000 0000000 00000013036 12301751702 031057 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.Credentials; import org.apache.http.auth.InvalidCredentialsException; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.auth.NTCredentials; import org.apache.http.message.BufferedHeader; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; /** * NTLM is a proprietary authentication scheme developed by Microsoft * and optimized for Windows platforms. * * @since 4.0 */ @NotThreadSafe public class NTLMScheme extends AuthSchemeBase { enum State { UNINITIATED, CHALLENGE_RECEIVED, MSG_TYPE1_GENERATED, MSG_TYPE2_RECEVIED, MSG_TYPE3_GENERATED, FAILED, } private final NTLMEngine engine; private State state; private String challenge; public NTLMScheme(final NTLMEngine engine) { super(); Args.notNull(engine, "NTLM engine"); this.engine = engine; this.state = State.UNINITIATED; this.challenge = null; } /** * @since 4.3 */ public NTLMScheme() { this(new NTLMEngineImpl()); } public String getSchemeName() { return "ntlm"; } public String getParameter(final String name) { // String parameters not supported return null; } public String getRealm() { // NTLM does not support the concept of an authentication realm return null; } public boolean isConnectionBased() { return true; } @Override protected void parseChallenge( final CharArrayBuffer buffer, final int beginIndex, final int endIndex) throws MalformedChallengeException { this.challenge = buffer.substringTrimmed(beginIndex, endIndex); if (this.challenge.length() == 0) { if (this.state == State.UNINITIATED) { this.state = State.CHALLENGE_RECEIVED; } else { this.state = State.FAILED; } } else { if (this.state.compareTo(State.MSG_TYPE1_GENERATED) < 0) { this.state = State.FAILED; throw new MalformedChallengeException("Out of sequence NTLM response message"); } else if (this.state == State.MSG_TYPE1_GENERATED) { this.state = State.MSG_TYPE2_RECEVIED; } } } public Header authenticate( final Credentials credentials, final HttpRequest request) throws AuthenticationException { NTCredentials ntcredentials = null; try { ntcredentials = (NTCredentials) credentials; } catch (final ClassCastException e) { throw new InvalidCredentialsException( "Credentials cannot be used for NTLM authentication: " + credentials.getClass().getName()); } String response = null; if (this.state == State.FAILED) { throw new AuthenticationException("NTLM authentication failed"); } else if (this.state == State.CHALLENGE_RECEIVED) { response = this.engine.generateType1Msg( ntcredentials.getDomain(), ntcredentials.getWorkstation()); this.state = State.MSG_TYPE1_GENERATED; } else if (this.state == State.MSG_TYPE2_RECEVIED) { response = this.engine.generateType3Msg( ntcredentials.getUserName(), ntcredentials.getPassword(), ntcredentials.getDomain(), ntcredentials.getWorkstation(), this.challenge); this.state = State.MSG_TYPE3_GENERATED; } else { throw new AuthenticationException("Unexpected state: " + this.state); } final CharArrayBuffer buffer = new CharArrayBuffer(32); if (isProxy()) { buffer.append(AUTH.PROXY_AUTH_RESP); } else { buffer.append(AUTH.WWW_AUTH_RESP); } buffer.append(": NTLM "); buffer.append(response); return new BufferedHeader(buffer); } public boolean isComplete() { return this.state == State.MSG_TYPE3_GENERATED || this.state == State.FAILED; } } ././@LongLink0100644 0000000 0000000 00000000146 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/NTLMSchemeFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/NTLMSchemeFactory.jav0100644 0000000 0000000 00000003740 12301751702 032247 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeFactory; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; /** * {@link AuthSchemeProvider} implementation that creates and initializes * {@link NTLMScheme} instances configured to use the default {@link NTLMEngine} * implementation. * * @since 4.1 */ @Immutable @SuppressWarnings("deprecation") public class NTLMSchemeFactory implements AuthSchemeFactory, AuthSchemeProvider { public AuthScheme newInstance(final HttpParams params) { return new NTLMScheme(); } public AuthScheme create(final HttpContext context) { return new NTLMScheme(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/package-info.java0100644 0000000 0000000 00000002436 12301751702 031506 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Default implementations of standard and common HTTP authentication * schemes. */ package org.apache.http.impl.auth; httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/RFC2617Scheme.java0100644 0000000 0000000 00000011535 12301751702 031241 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.apache.http.Consts; import org.apache.http.HeaderElement; import org.apache.http.HttpRequest; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.ChallengeState; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.auth.params.AuthPNames; import org.apache.http.message.BasicHeaderValueParser; import org.apache.http.message.HeaderValueParser; import org.apache.http.message.ParserCursor; import org.apache.http.util.CharArrayBuffer; /** * Abstract authentication scheme class that lays foundation for all * RFC 2617 compliant authentication schemes and provides capabilities common * to all authentication schemes defined in RFC 2617. * * @since 4.0 */ @SuppressWarnings("deprecation") @NotThreadSafe // AuthSchemeBase, params public abstract class RFC2617Scheme extends AuthSchemeBase { private final Map params; private final Charset credentialsCharset; /** * Creates an instance of RFC2617Scheme with the given challenge * state. * * @since 4.2 * * @deprecated (4.3) do not use. */ @Deprecated public RFC2617Scheme(final ChallengeState challengeState) { super(challengeState); this.params = new HashMap(); this.credentialsCharset = Consts.ASCII; } /** * @since 4.3 */ public RFC2617Scheme(final Charset credentialsCharset) { super(); this.params = new HashMap(); this.credentialsCharset = credentialsCharset != null ? credentialsCharset : Consts.ASCII; } public RFC2617Scheme() { this(Consts.ASCII); } /** * @since 4.3 */ public Charset getCredentialsCharset() { return credentialsCharset; } String getCredentialsCharset(final HttpRequest request) { String charset = (String) request.getParams().getParameter(AuthPNames.CREDENTIAL_CHARSET); if (charset == null) { charset = getCredentialsCharset().name(); } return charset; } @Override protected void parseChallenge( final CharArrayBuffer buffer, final int pos, final int len) throws MalformedChallengeException { final HeaderValueParser parser = BasicHeaderValueParser.INSTANCE; final ParserCursor cursor = new ParserCursor(pos, buffer.length()); final HeaderElement[] elements = parser.parseElements(buffer, cursor); if (elements.length == 0) { throw new MalformedChallengeException("Authentication challenge is empty"); } this.params.clear(); for (final HeaderElement element : elements) { this.params.put(element.getName(), element.getValue()); } } /** * Returns authentication parameters map. Keys in the map are lower-cased. * * @return the map of authentication parameters */ protected Map getParameters() { return this.params; } /** * Returns authentication parameter with the given name, if available. * * @param name The name of the parameter to be returned * * @return the parameter with the given name */ public String getParameter(final String name) { if (name == null) { return null; } return this.params.get(name.toLowerCase(Locale.ENGLISH)); } /** * Returns authentication realm. The realm may not be null. * * @return the authentication realm */ public String getRealm() { return getParameter("realm"); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoScheme.java0100644 0000000 0000000 00000007127 12301751702 031444 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.Credentials; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.ietf.jgss.GSSException; import org.ietf.jgss.Oid; /** * SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) authentication * scheme. * * @since 4.2 */ @NotThreadSafe public class SPNegoScheme extends GGSSchemeBase { private static final String SPNEGO_OID = "1.3.6.1.5.5.2"; public SPNegoScheme(final boolean stripPort) { super(stripPort); } public SPNegoScheme() { super(false); } public String getSchemeName() { return "Negotiate"; } /** * Produces SPNEGO authorization Header based on token created by * processChallenge. * * @param credentials not used by the SPNEGO scheme. * @param request The request being authenticated * * @throws AuthenticationException if authentication string cannot * be generated due to an authentication failure * * @return SPNEGO authentication Header */ @Override public Header authenticate( final Credentials credentials, final HttpRequest request, final HttpContext context) throws AuthenticationException { return super.authenticate(credentials, request, context); } @Override protected byte[] generateToken(final byte[] input, final String authServer) throws GSSException { return generateGSSToken(input, new Oid(SPNEGO_OID), authServer); } /** * There are no valid parameters for SPNEGO authentication so this * method always returns null. * * @return null */ public String getParameter(final String name) { Args.notNull(name, "Parameter name"); return null; } /** * The concept of an authentication realm is not supported by the Negotiate * authentication scheme. Always returns null. * * @return null */ public String getRealm() { return null; } /** * Returns true. SPNEGO authentication scheme is connection based. * * @return true. */ public boolean isConnectionBased() { return true; } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoSchemeFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoSchemeFactory.j0100644 0000000 0000000 00000004337 12301751702 032304 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeFactory; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; /** * {@link AuthSchemeProvider} implementation that creates and initializes * {@link SPNegoScheme} instances. * * @since 4.2 */ @Immutable @SuppressWarnings("deprecation") public class SPNegoSchemeFactory implements AuthSchemeFactory, AuthSchemeProvider { private final boolean stripPort; public SPNegoSchemeFactory(final boolean stripPort) { super(); this.stripPort = stripPort; } public SPNegoSchemeFactory() { this(false); } public boolean isStripPort() { return stripPort; } public AuthScheme newInstance(final HttpParams params) { return new SPNegoScheme(this.stripPort); } public AuthScheme create(final HttpContext context) { return new SPNegoScheme(this.stripPort); } } ././@LongLink0100644 0000000 0000000 00000000170 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/UnsupportedDigestAlgorithmException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/auth/UnsupportedDigestAlgo0100644 0000000 0000000 00000004627 12301751702 032541 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import org.apache.http.annotation.Immutable; /** * Authentication credentials required to respond to a authentication * challenge are invalid * * * @since 4.0 */ @Immutable public class UnsupportedDigestAlgorithmException extends RuntimeException { private static final long serialVersionUID = 319558534317118022L; /** * Creates a new UnsupportedAuthAlgoritmException with a null detail message. */ public UnsupportedDigestAlgorithmException() { super(); } /** * Creates a new UnsupportedAuthAlgoritmException with the specified message. * * @param message the exception detail message */ public UnsupportedDigestAlgorithmException(final String message) { super(message); } /** * Creates a new UnsupportedAuthAlgoritmException with the specified detail message and cause. * * @param message the exception detail message * @param cause the Throwable that caused this exception, or null * if the cause is unavailable, unknown, or not a Throwable */ public UnsupportedDigestAlgorithmException(final String message, final Throwable cause) { super(message, cause); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/0040755 0000000 0000000 00000000000 12301751711 026632 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/AIMDBackoffManager.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/AIMDBackoffManager.0100644 0000000 0000000 00000014326 12301751711 032117 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.HashMap; import java.util.Map; import org.apache.http.client.BackoffManager; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.pool.ConnPoolControl; import org.apache.http.util.Args; /** *

The AIMDBackoffManager applies an additive increase, * multiplicative decrease (AIMD) to managing a dynamic limit to * the number of connections allowed to a given host. You may want * to experiment with the settings for the cooldown periods and the * backoff factor to get the adaptive behavior you want.

* *

Generally speaking, shorter cooldowns will lead to more steady-state * variability but faster reaction times, while longer cooldowns * will lead to more stable equilibrium behavior but slower reaction * times.

* *

Similarly, higher backoff factors promote greater * utilization of available capacity at the expense of fairness * among clients. Lower backoff factors allow equal distribution of * capacity among clients (fairness) to happen faster, at the * expense of having more server capacity unused in the short term.

* * @since 4.2 */ public class AIMDBackoffManager implements BackoffManager { private final ConnPoolControl connPerRoute; private final Clock clock; private final Map lastRouteProbes; private final Map lastRouteBackoffs; private long coolDown = 5 * 1000L; private double backoffFactor = 0.5; private int cap = 2; // Per RFC 2616 sec 8.1.4 /** * Creates an AIMDBackoffManager to manage * per-host connection pool sizes represented by the * given {@link ConnPoolControl}. * @param connPerRoute per-host routing maximums to * be managed */ public AIMDBackoffManager(final ConnPoolControl connPerRoute) { this(connPerRoute, new SystemClock()); } AIMDBackoffManager(final ConnPoolControl connPerRoute, final Clock clock) { this.clock = clock; this.connPerRoute = connPerRoute; this.lastRouteProbes = new HashMap(); this.lastRouteBackoffs = new HashMap(); } public void backOff(final HttpRoute route) { synchronized(connPerRoute) { final int curr = connPerRoute.getMaxPerRoute(route); final Long lastUpdate = getLastUpdate(lastRouteBackoffs, route); final long now = clock.getCurrentTime(); if (now - lastUpdate.longValue() < coolDown) { return; } connPerRoute.setMaxPerRoute(route, getBackedOffPoolSize(curr)); lastRouteBackoffs.put(route, Long.valueOf(now)); } } private int getBackedOffPoolSize(final int curr) { if (curr <= 1) { return 1; } return (int)(Math.floor(backoffFactor * curr)); } public void probe(final HttpRoute route) { synchronized(connPerRoute) { final int curr = connPerRoute.getMaxPerRoute(route); final int max = (curr >= cap) ? cap : curr + 1; final Long lastProbe = getLastUpdate(lastRouteProbes, route); final Long lastBackoff = getLastUpdate(lastRouteBackoffs, route); final long now = clock.getCurrentTime(); if (now - lastProbe.longValue() < coolDown || now - lastBackoff.longValue() < coolDown) { return; } connPerRoute.setMaxPerRoute(route, max); lastRouteProbes.put(route, Long.valueOf(now)); } } private Long getLastUpdate(final Map updates, final HttpRoute route) { Long lastUpdate = updates.get(route); if (lastUpdate == null) { lastUpdate = Long.valueOf(0L); } return lastUpdate; } /** * Sets the factor to use when backing off; the new * per-host limit will be roughly the current max times * this factor. Math.floor is applied in the * case of non-integer outcomes to ensure we actually * decrease the pool size. Pool sizes are never decreased * below 1, however. Defaults to 0.5. * @param d must be between 0.0 and 1.0, exclusive. */ public void setBackoffFactor(final double d) { Args.check(d > 0.0 && d < 1.0, "Backoff factor must be 0.0 < f < 1.0"); backoffFactor = d; } /** * Sets the amount of time, in milliseconds, to wait between * adjustments in pool sizes for a given host, to allow * enough time for the adjustments to take effect. Defaults * to 5000L (5 seconds). * @param l must be positive */ public void setCooldownMillis(final long l) { Args.positive(coolDown, "Cool down"); coolDown = l; } /** * Sets the absolute maximum per-host connection pool size to * probe up to; defaults to 2 (the default per-host max). * @param cap must be >= 1 */ public void setPerHostConnectionCap(final int cap) { Args.positive(cap, "Per host connection cap"); this.cap = cap; } } ././@LongLink0100644 0000000 0000000 00000000161 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/AuthenticationStrategyImpl.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/AuthenticationStrat0100644 0000000 0000000 00000023136 12301751711 032554 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Queue; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.FormattedHeader; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthOption; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.client.AuthCache; import org.apache.http.client.AuthenticationStrategy; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.AuthSchemes; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.Lookup; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; @Immutable abstract class AuthenticationStrategyImpl implements AuthenticationStrategy { private final Log log = LogFactory.getLog(getClass()); private static final List DEFAULT_SCHEME_PRIORITY = Collections.unmodifiableList(Arrays.asList(AuthSchemes.SPNEGO, AuthSchemes.KERBEROS, AuthSchemes.NTLM, AuthSchemes.DIGEST, AuthSchemes.BASIC)); private final int challengeCode; private final String headerName; AuthenticationStrategyImpl(final int challengeCode, final String headerName) { super(); this.challengeCode = challengeCode; this.headerName = headerName; } public boolean isAuthenticationRequested( final HttpHost authhost, final HttpResponse response, final HttpContext context) { Args.notNull(response, "HTTP response"); final int status = response.getStatusLine().getStatusCode(); return status == this.challengeCode; } public Map getChallenges( final HttpHost authhost, final HttpResponse response, final HttpContext context) throws MalformedChallengeException { Args.notNull(response, "HTTP response"); final Header[] headers = response.getHeaders(this.headerName); final Map map = new HashMap(headers.length); for (final Header header : headers) { final CharArrayBuffer buffer; int pos; if (header instanceof FormattedHeader) { buffer = ((FormattedHeader) header).getBuffer(); pos = ((FormattedHeader) header).getValuePos(); } else { final String s = header.getValue(); if (s == null) { throw new MalformedChallengeException("Header value is null"); } buffer = new CharArrayBuffer(s.length()); buffer.append(s); pos = 0; } while (pos < buffer.length() && HTTP.isWhitespace(buffer.charAt(pos))) { pos++; } final int beginIndex = pos; while (pos < buffer.length() && !HTTP.isWhitespace(buffer.charAt(pos))) { pos++; } final int endIndex = pos; final String s = buffer.substring(beginIndex, endIndex); map.put(s.toLowerCase(Locale.US), header); } return map; } abstract Collection getPreferredAuthSchemes(RequestConfig config); public Queue select( final Map challenges, final HttpHost authhost, final HttpResponse response, final HttpContext context) throws MalformedChallengeException { Args.notNull(challenges, "Map of auth challenges"); Args.notNull(authhost, "Host"); Args.notNull(response, "HTTP response"); Args.notNull(context, "HTTP context"); final HttpClientContext clientContext = HttpClientContext.adapt(context); final Queue options = new LinkedList(); final Lookup registry = clientContext.getAuthSchemeRegistry(); if (registry == null) { this.log.debug("Auth scheme registry not set in the context"); return options; } final CredentialsProvider credsProvider = clientContext.getCredentialsProvider(); if (credsProvider == null) { this.log.debug("Credentials provider not set in the context"); return options; } final RequestConfig config = clientContext.getRequestConfig(); Collection authPrefs = getPreferredAuthSchemes(config); if (authPrefs == null) { authPrefs = DEFAULT_SCHEME_PRIORITY; } if (this.log.isDebugEnabled()) { this.log.debug("Authentication schemes in the order of preference: " + authPrefs); } for (final String id: authPrefs) { final Header challenge = challenges.get(id.toLowerCase(Locale.US)); if (challenge != null) { final AuthSchemeProvider authSchemeProvider = registry.lookup(id); if (authSchemeProvider == null) { if (this.log.isWarnEnabled()) { this.log.warn("Authentication scheme " + id + " not supported"); // Try again } continue; } final AuthScheme authScheme = authSchemeProvider.create(context); authScheme.processChallenge(challenge); final AuthScope authScope = new AuthScope( authhost.getHostName(), authhost.getPort(), authScheme.getRealm(), authScheme.getSchemeName()); final Credentials credentials = credsProvider.getCredentials(authScope); if (credentials != null) { options.add(new AuthOption(authScheme, credentials)); } } else { if (this.log.isDebugEnabled()) { this.log.debug("Challenge for " + id + " authentication scheme not available"); // Try again } } } return options; } public void authSucceeded( final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) { Args.notNull(authhost, "Host"); Args.notNull(authScheme, "Auth scheme"); Args.notNull(context, "HTTP context"); final HttpClientContext clientContext = HttpClientContext.adapt(context); if (isCachable(authScheme)) { AuthCache authCache = clientContext.getAuthCache(); if (authCache == null) { authCache = new BasicAuthCache(); clientContext.setAuthCache(authCache); } if (this.log.isDebugEnabled()) { this.log.debug("Caching '" + authScheme.getSchemeName() + "' auth scheme for " + authhost); } authCache.put(authhost, authScheme); } } protected boolean isCachable(final AuthScheme authScheme) { if (authScheme == null || !authScheme.isComplete()) { return false; } final String schemeName = authScheme.getSchemeName(); return schemeName.equalsIgnoreCase(AuthSchemes.BASIC) || schemeName.equalsIgnoreCase(AuthSchemes.DIGEST); } public void authFailed( final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) { Args.notNull(authhost, "Host"); Args.notNull(context, "HTTP context"); final HttpClientContext clientContext = HttpClientContext.adapt(context); final AuthCache authCache = clientContext.getAuthCache(); if (authCache != null) { if (this.log.isDebugEnabled()) { this.log.debug("Clearing cached auth scheme for " + authhost); } authCache.remove(authhost); } } } ././@LongLink0100644 0000000 0000000 00000000145 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/BasicAuthCache.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/BasicAuthCache.java0100644 0000000 0000000 00000006345 12301751710 032270 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.HashMap; import org.apache.http.HttpHost; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AuthScheme; import org.apache.http.client.AuthCache; import org.apache.http.conn.SchemePortResolver; import org.apache.http.conn.UnsupportedSchemeException; import org.apache.http.impl.conn.DefaultSchemePortResolver; import org.apache.http.util.Args; /** * Default implementation of {@link AuthCache}. * * @since 4.0 */ @NotThreadSafe public class BasicAuthCache implements AuthCache { private final HashMap map; private final SchemePortResolver schemePortResolver; /** * Default constructor. * * @since 4.3 */ public BasicAuthCache(final SchemePortResolver schemePortResolver) { super(); this.map = new HashMap(); this.schemePortResolver = schemePortResolver != null ? schemePortResolver : DefaultSchemePortResolver.INSTANCE; } public BasicAuthCache() { this(null); } protected HttpHost getKey(final HttpHost host) { if (host.getPort() <= 0) { final int port; try { port = schemePortResolver.resolve(host); } catch (final UnsupportedSchemeException ignore) { return host; } return new HttpHost(host.getHostName(), port, host.getSchemeName()); } else { return host; } } public void put(final HttpHost host, final AuthScheme authScheme) { Args.notNull(host, "HTTP host"); this.map.put(getKey(host), authScheme); } public AuthScheme get(final HttpHost host) { Args.notNull(host, "HTTP host"); return this.map.get(getKey(host)); } public void remove(final HttpHost host) { Args.notNull(host, "HTTP host"); this.map.remove(getKey(host)); } public void clear() { this.map.clear(); } @Override public String toString() { return this.map.toString(); } } ././@LongLink0100644 0000000 0000000 00000000147 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/BasicCookieStore.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/BasicCookieStore.ja0100644 0000000 0000000 00000010610 12301751710 032330 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.TreeSet; import org.apache.http.annotation.GuardedBy; import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.CookieStore; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieIdentityComparator; /** * Default implementation of {@link CookieStore} * * * @since 4.0 */ @ThreadSafe public class BasicCookieStore implements CookieStore, Serializable { private static final long serialVersionUID = -7581093305228232025L; @GuardedBy("this") private final TreeSet cookies; public BasicCookieStore() { super(); this.cookies = new TreeSet(new CookieIdentityComparator()); } /** * Adds an {@link Cookie HTTP cookie}, replacing any existing equivalent cookies. * If the given cookie has already expired it will not be added, but existing * values will still be removed. * * @param cookie the {@link Cookie cookie} to be added * * @see #addCookies(Cookie[]) * */ public synchronized void addCookie(final Cookie cookie) { if (cookie != null) { // first remove any old cookie that is equivalent cookies.remove(cookie); if (!cookie.isExpired(new Date())) { cookies.add(cookie); } } } /** * Adds an array of {@link Cookie HTTP cookies}. Cookies are added individually and * in the given array order. If any of the given cookies has already expired it will * not be added, but existing values will still be removed. * * @param cookies the {@link Cookie cookies} to be added * * @see #addCookie(Cookie) * */ public synchronized void addCookies(final Cookie[] cookies) { if (cookies != null) { for (final Cookie cooky : cookies) { this.addCookie(cooky); } } } /** * Returns an immutable array of {@link Cookie cookies} that this HTTP * state currently contains. * * @return an array of {@link Cookie cookies}. */ public synchronized List getCookies() { //create defensive copy so it won't be concurrently modified return new ArrayList(cookies); } /** * Removes all of {@link Cookie cookies} in this HTTP state * that have expired by the specified {@link java.util.Date date}. * * @return true if any cookies were purged. * * @see Cookie#isExpired(Date) */ public synchronized boolean clearExpired(final Date date) { if (date == null) { return false; } boolean removed = false; for (final Iterator it = cookies.iterator(); it.hasNext();) { if (it.next().isExpired(date)) { it.remove(); removed = true; } } return removed; } /** * Clears all cookies. */ public synchronized void clear() { cookies.clear(); } @Override public synchronized String toString() { return cookies.toString(); } } ././@LongLink0100644 0000000 0000000 00000000157 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/BasicCredentialsProvider.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/BasicCredentialsPro0100644 0000000 0000000 00000006742 12301751710 032442 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.http.annotation.ThreadSafe; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.util.Args; /** * Default implementation of {@link CredentialsProvider}. * * @since 4.0 */ @ThreadSafe public class BasicCredentialsProvider implements CredentialsProvider { private final ConcurrentHashMap credMap; /** * Default constructor. */ public BasicCredentialsProvider() { super(); this.credMap = new ConcurrentHashMap(); } public void setCredentials( final AuthScope authscope, final Credentials credentials) { Args.notNull(authscope, "Authentication scope"); credMap.put(authscope, credentials); } /** * Find matching {@link Credentials credentials} for the given authentication scope. * * @param map the credentials hash map * @param authscope the {@link AuthScope authentication scope} * @return the credentials * */ private static Credentials matchCredentials( final Map map, final AuthScope authscope) { // see if we get a direct hit Credentials creds = map.get(authscope); if (creds == null) { // Nope. // Do a full scan int bestMatchFactor = -1; AuthScope bestMatch = null; for (final AuthScope current: map.keySet()) { final int factor = authscope.match(current); if (factor > bestMatchFactor) { bestMatchFactor = factor; bestMatch = current; } } if (bestMatch != null) { creds = map.get(bestMatch); } } return creds; } public Credentials getCredentials(final AuthScope authscope) { Args.notNull(authscope, "Authentication scope"); return matchCredentials(this.credMap, authscope); } public void clear() { this.credMap.clear(); } @Override public String toString() { return credMap.toString(); } } ././@LongLink0100644 0000000 0000000 00000000153 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/BasicResponseHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/BasicResponseHandle0100644 0000000 0000000 00000005535 12301751711 032436 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.IOException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.annotation.Immutable; import org.apache.http.client.HttpResponseException; import org.apache.http.client.ResponseHandler; import org.apache.http.util.EntityUtils; /** * A {@link ResponseHandler} that returns the response body as a String * for successful (2xx) responses. If the response code was >= 300, the response * body is consumed and an {@link HttpResponseException} is thrown. *

* If this is used with * {@link org.apache.http.client.HttpClient#execute( * org.apache.http.client.methods.HttpUriRequest, ResponseHandler)}, * HttpClient may handle redirects (3xx responses) internally. * * @since 4.0 */ @Immutable public class BasicResponseHandler implements ResponseHandler { /** * Returns the response body as a String if the response was successful (a * 2xx status code). If no response body exists, this returns null. If the * response was unsuccessful (>= 300 status code), throws an * {@link HttpResponseException}. */ public String handleResponse(final HttpResponse response) throws HttpResponseException, IOException { final StatusLine statusLine = response.getStatusLine(); final HttpEntity entity = response.getEntity(); if (statusLine.getStatusCode() >= 300) { EntityUtils.consume(entity); throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase()); } return entity == null ? null : EntityUtils.toString(entity); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/Clock.java0100644 0000000 0000000 00000002744 12301751711 030534 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; /** * Interface used to enable easier testing of time-related behavior. * * @since 4.2 * */ interface Clock { /** * Returns the current time, expressed as the number of * milliseconds since the epoch. * @return current time */ long getCurrentTime(); } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/CloseableHttpClient.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/CloseableHttpClient0100644 0000000 0000000 00000024214 12301751710 032444 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.Closeable; import java.io.IOException; import java.lang.reflect.UndeclaredThrowableException; import java.net.URI; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.utils.URIUtils; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.EntityUtils; /** * Base implementation of {@link HttpClient} that also implements {@link Closeable}. * * @since 4.3 */ @ThreadSafe public abstract class CloseableHttpClient implements HttpClient, Closeable { private final Log log = LogFactory.getLog(getClass()); protected abstract CloseableHttpResponse doExecute(HttpHost target, HttpRequest request, HttpContext context) throws IOException, ClientProtocolException; /** * {@inheritDoc} */ public CloseableHttpResponse execute( final HttpHost target, final HttpRequest request, final HttpContext context) throws IOException, ClientProtocolException { return doExecute(target, request, context); } /** * {@inheritDoc} */ public CloseableHttpResponse execute( final HttpUriRequest request, final HttpContext context) throws IOException, ClientProtocolException { Args.notNull(request, "HTTP request"); return doExecute(determineTarget(request), request, context); } private static HttpHost determineTarget(final HttpUriRequest request) throws ClientProtocolException { // A null target may be acceptable if there is a default target. // Otherwise, the null target is detected in the director. HttpHost target = null; final URI requestURI = request.getURI(); if (requestURI.isAbsolute()) { target = URIUtils.extractHost(requestURI); if (target == null) { throw new ClientProtocolException("URI does not specify a valid host name: " + requestURI); } } return target; } /** * {@inheritDoc} */ public CloseableHttpResponse execute( final HttpUriRequest request) throws IOException, ClientProtocolException { return execute(request, (HttpContext) null); } /** * {@inheritDoc} */ public CloseableHttpResponse execute( final HttpHost target, final HttpRequest request) throws IOException, ClientProtocolException { return doExecute(target, request, (HttpContext) null); } /** * Executes a request using the default context and processes the * response using the given response handler. The content entity associated * with the response is fully consumed and the underlying connection is * released back to the connection manager automatically in all cases * relieving individual {@link ResponseHandler}s from having to manage * resource deallocation internally. * * @param request the request to execute * @param responseHandler the response handler * * @return the response object as generated by the response handler. * @throws IOException in case of a problem or the connection was aborted * @throws ClientProtocolException in case of an http protocol error */ public T execute(final HttpUriRequest request, final ResponseHandler responseHandler) throws IOException, ClientProtocolException { return execute(request, responseHandler, null); } /** * Executes a request using the default context and processes the * response using the given response handler. The content entity associated * with the response is fully consumed and the underlying connection is * released back to the connection manager automatically in all cases * relieving individual {@link ResponseHandler}s from having to manage * resource deallocation internally. * * @param request the request to execute * @param responseHandler the response handler * @param context the context to use for the execution, or * null to use the default context * * @return the response object as generated by the response handler. * @throws IOException in case of a problem or the connection was aborted * @throws ClientProtocolException in case of an http protocol error */ public T execute(final HttpUriRequest request, final ResponseHandler responseHandler, final HttpContext context) throws IOException, ClientProtocolException { final HttpHost target = determineTarget(request); return execute(target, request, responseHandler, context); } /** * Executes a request using the default context and processes the * response using the given response handler. The content entity associated * with the response is fully consumed and the underlying connection is * released back to the connection manager automatically in all cases * relieving individual {@link ResponseHandler}s from having to manage * resource deallocation internally. * * @param target the target host for the request. * Implementations may accept null * if they can still determine a route, for example * to a default target or by inspecting the request. * @param request the request to execute * @param responseHandler the response handler * * @return the response object as generated by the response handler. * @throws IOException in case of a problem or the connection was aborted * @throws ClientProtocolException in case of an http protocol error */ public T execute(final HttpHost target, final HttpRequest request, final ResponseHandler responseHandler) throws IOException, ClientProtocolException { return execute(target, request, responseHandler, null); } /** * Executes a request using the default context and processes the * response using the given response handler. The content entity associated * with the response is fully consumed and the underlying connection is * released back to the connection manager automatically in all cases * relieving individual {@link ResponseHandler}s from having to manage * resource deallocation internally. * * @param target the target host for the request. * Implementations may accept null * if they can still determine a route, for example * to a default target or by inspecting the request. * @param request the request to execute * @param responseHandler the response handler * @param context the context to use for the execution, or * null to use the default context * * @return the response object as generated by the response handler. * @throws IOException in case of a problem or the connection was aborted * @throws ClientProtocolException in case of an http protocol error */ public T execute(final HttpHost target, final HttpRequest request, final ResponseHandler responseHandler, final HttpContext context) throws IOException, ClientProtocolException { Args.notNull(responseHandler, "Response handler"); final HttpResponse response = execute(target, request, context); final T result; try { result = responseHandler.handleResponse(response); } catch (final Exception t) { final HttpEntity entity = response.getEntity(); try { EntityUtils.consume(entity); } catch (final Exception t2) { // Log this exception. The original exception is more // important and will be thrown to the caller. this.log.warn("Error consuming content after an exception.", t2); } if (t instanceof RuntimeException) { throw (RuntimeException) t; } if (t instanceof IOException) { throw (IOException) t; } throw new UndeclaredThrowableException(t); } // Handling the response was successful. Ensure that the content has // been fully consumed. final HttpEntity entity = response.getEntity(); EntityUtils.consume(entity); return result; } } ././@LongLink0100644 0000000 0000000 00000000161 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/CloseableHttpResponseProxy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/CloseableHttpRespon0100644 0000000 0000000 00000005713 12301751710 032477 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.util.EntityUtils; /** * @since 4.3 */ @NotThreadSafe class CloseableHttpResponseProxy implements InvocationHandler { private final HttpResponse original; CloseableHttpResponseProxy(final HttpResponse original) { super(); this.original = original; } public void close() throws IOException { final HttpEntity entity = this.original.getEntity(); EntityUtils.consume(entity); } public Object invoke( final Object proxy, final Method method, final Object[] args) throws Throwable { final String mname = method.getName(); if (mname.equals("close")) { close(); return null; } else { try { return method.invoke(original, args); } catch (final InvocationTargetException ex) { final Throwable cause = ex.getCause(); if (cause != null) { throw cause; } else { throw ex; } } } } public static CloseableHttpResponse newProxy(final HttpResponse original) { return (CloseableHttpResponse) Proxy.newProxyInstance( CloseableHttpResponseProxy.class.getClassLoader(), new Class[] { CloseableHttpResponse.class }, new CloseableHttpResponseProxy(original)); } } ././@LongLink0100644 0000000 0000000 00000000155 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/DefaultBackoffStrategy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/DefaultBackoffStrat0100644 0000000 0000000 00000003765 12301751711 032443 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.net.ConnectException; import java.net.SocketTimeoutException; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.ConnectionBackoffStrategy; /** * This {@link ConnectionBackoffStrategy} backs off either for a raw * network socket or connection timeout or if the server explicitly * sends a 503 (Service Unavailable) response. * * @since 4.2 */ public class DefaultBackoffStrategy implements ConnectionBackoffStrategy { public boolean shouldBackoff(final Throwable t) { return (t instanceof SocketTimeoutException || t instanceof ConnectException); } public boolean shouldBackoff(final HttpResponse resp) { return (resp.getStatusLine().getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE); } } ././@LongLink0100644 0000000 0000000 00000000171 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/DefaultConnectionKeepAliveStrategy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/DefaultConnectionKe0100644 0000000 0000000 00000005351 12301751710 032441 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.HeaderElement; import org.apache.http.HeaderElementIterator; import org.apache.http.HttpResponse; import org.apache.http.annotation.Immutable; import org.apache.http.conn.ConnectionKeepAliveStrategy; import org.apache.http.message.BasicHeaderElementIterator; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Default implementation of a strategy deciding duration * that a connection can remain idle. * * The default implementation looks solely at the 'Keep-Alive' * header's timeout token. * * @since 4.0 */ @Immutable public class DefaultConnectionKeepAliveStrategy implements ConnectionKeepAliveStrategy { public static final DefaultConnectionKeepAliveStrategy INSTANCE = new DefaultConnectionKeepAliveStrategy(); public long getKeepAliveDuration(final HttpResponse response, final HttpContext context) { Args.notNull(response, "HTTP response"); final HeaderElementIterator it = new BasicHeaderElementIterator( response.headerIterator(HTTP.CONN_KEEP_ALIVE)); while (it.hasNext()) { final HeaderElement he = it.nextElement(); final String param = he.getName(); final String value = he.getValue(); if (value != null && param.equalsIgnoreCase("timeout")) { try { return Long.parseLong(value) * 1000; } catch(final NumberFormatException ignore) { } } } return -1; } } ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/DefaultHttpRequestRetryHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/DefaultHttpRequestR0100644 0000000 0000000 00000016061 12301751710 032474 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.IOException; import java.io.InterruptedIOException; import java.net.ConnectException; import java.net.UnknownHostException; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Set; import javax.net.ssl.SSLException; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.annotation.Immutable; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * The default {@link HttpRequestRetryHandler} used by request executors. * * @since 4.0 */ @Immutable public class DefaultHttpRequestRetryHandler implements HttpRequestRetryHandler { public static final DefaultHttpRequestRetryHandler INSTANCE = new DefaultHttpRequestRetryHandler(); /** the number of times a method will be retried */ private final int retryCount; /** Whether or not methods that have successfully sent their request will be retried */ private final boolean requestSentRetryEnabled; private final Set> nonRetriableClasses; /** * Create the request retry handler using the specified IOException classes * * @param retryCount how many times to retry; 0 means no retries * @param requestSentRetryEnabled true if it's OK to retry requests that have been sent * @param clazzes the IOException types that should not be retried * @since 4.3 */ protected DefaultHttpRequestRetryHandler( final int retryCount, final boolean requestSentRetryEnabled, final Collection> clazzes) { super(); this.retryCount = retryCount; this.requestSentRetryEnabled = requestSentRetryEnabled; this.nonRetriableClasses = new HashSet>(); for (final Class clazz: clazzes) { this.nonRetriableClasses.add(clazz); } } /** * Create the request retry handler using the following list of * non-retriable IOException classes:
*

    *
  • InterruptedIOException
  • *
  • UnknownHostException
  • *
  • ConnectException
  • *
  • SSLException
  • *
* @param retryCount how many times to retry; 0 means no retries * @param requestSentRetryEnabled true if it's OK to retry requests that have been sent */ @SuppressWarnings("unchecked") public DefaultHttpRequestRetryHandler(final int retryCount, final boolean requestSentRetryEnabled) { this(retryCount, requestSentRetryEnabled, Arrays.asList( InterruptedIOException.class, UnknownHostException.class, ConnectException.class, SSLException.class)); } /** * Create the request retry handler with a retry count of 3, requestSentRetryEnabled false * and using the following list of non-retriable IOException classes:
*
    *
  • InterruptedIOException
  • *
  • UnknownHostException
  • *
  • ConnectException
  • *
  • SSLException
  • *
*/ public DefaultHttpRequestRetryHandler() { this(3, false); } /** * Used retryCount and requestSentRetryEnabled to determine * if the given method should be retried. */ public boolean retryRequest( final IOException exception, final int executionCount, final HttpContext context) { Args.notNull(exception, "Exception parameter"); Args.notNull(context, "HTTP context"); if (executionCount > this.retryCount) { // Do not retry if over max retry count return false; } if (this.nonRetriableClasses.contains(exception.getClass())) { return false; } else { for (final Class rejectException : this.nonRetriableClasses) { if (rejectException.isInstance(exception)) { return false; } } } final HttpClientContext clientContext = HttpClientContext.adapt(context); final HttpRequest request = clientContext.getRequest(); if(requestIsAborted(request)){ return false; } if (handleAsIdempotent(request)) { // Retry if the request is considered idempotent return true; } if (!clientContext.isRequestSent() || this.requestSentRetryEnabled) { // Retry if the request has not been sent fully or // if it's OK to retry methods that have been sent return true; } // otherwise do not retry return false; } /** * @return true if this handler will retry methods that have * successfully sent their request, false otherwise */ public boolean isRequestSentRetryEnabled() { return requestSentRetryEnabled; } /** * @return the maximum number of times a method will be retried */ public int getRetryCount() { return retryCount; } /** * @since 4.2 */ protected boolean handleAsIdempotent(final HttpRequest request) { return !(request instanceof HttpEntityEnclosingRequest); } /** * @since 4.2 * * @deprecated (4.3) */ @Deprecated protected boolean requestIsAborted(final HttpRequest request) { HttpRequest req = request; if (request instanceof RequestWrapper) { // does not forward request to original req = ((RequestWrapper) request).getOriginal(); } return (req instanceof HttpUriRequest && ((HttpUriRequest)req).isAborted()); } } ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/DefaultRedirectStrategy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/DefaultRedirectStra0100644 0000000 0000000 00000021632 12301751710 032455 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.net.URI; import java.net.URISyntaxException; import java.util.Locale; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.ProtocolException; import org.apache.http.annotation.Immutable; import org.apache.http.client.CircularRedirectException; import org.apache.http.client.RedirectStrategy; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.URIBuilder; import org.apache.http.client.utils.URIUtils; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.Asserts; import org.apache.http.util.TextUtils; /** * Default implementation of {@link RedirectStrategy}. This strategy honors the restrictions * on automatic redirection of entity enclosing methods such as POST and PUT imposed by the * HTTP specification. 302 Moved Temporarily, 301 Moved Permanently and * 307 Temporary Redirect status codes will result in an automatic redirect of * HEAD and GET methods only. POST and PUT methods will not be automatically redirected * as requiring user confirmation. *

* The restriction on automatic redirection of POST methods can be relaxed by using * {@link LaxRedirectStrategy} instead of {@link DefaultRedirectStrategy}. * * @see LaxRedirectStrategy * @since 4.1 */ @Immutable public class DefaultRedirectStrategy implements RedirectStrategy { private final Log log = LogFactory.getLog(getClass()); /** * @deprecated (4.3) use {@link org.apache.http.client.protocol.HttpClientContext#REDIRECT_LOCATIONS}. */ @Deprecated public static final String REDIRECT_LOCATIONS = "http.protocol.redirect-locations"; public static final DefaultRedirectStrategy INSTANCE = new DefaultRedirectStrategy(); /** * Redirectable methods. */ private static final String[] REDIRECT_METHODS = new String[] { HttpGet.METHOD_NAME, HttpHead.METHOD_NAME }; public DefaultRedirectStrategy() { super(); } public boolean isRedirected( final HttpRequest request, final HttpResponse response, final HttpContext context) throws ProtocolException { Args.notNull(request, "HTTP request"); Args.notNull(response, "HTTP response"); final int statusCode = response.getStatusLine().getStatusCode(); final String method = request.getRequestLine().getMethod(); final Header locationHeader = response.getFirstHeader("location"); switch (statusCode) { case HttpStatus.SC_MOVED_TEMPORARILY: return isRedirectable(method) && locationHeader != null; case HttpStatus.SC_MOVED_PERMANENTLY: case HttpStatus.SC_TEMPORARY_REDIRECT: return isRedirectable(method); case HttpStatus.SC_SEE_OTHER: return true; default: return false; } //end of switch } public URI getLocationURI( final HttpRequest request, final HttpResponse response, final HttpContext context) throws ProtocolException { Args.notNull(request, "HTTP request"); Args.notNull(response, "HTTP response"); Args.notNull(context, "HTTP context"); final HttpClientContext clientContext = HttpClientContext.adapt(context); //get the location header to find out where to redirect to final Header locationHeader = response.getFirstHeader("location"); if (locationHeader == null) { // got a redirect response, but no location header throw new ProtocolException( "Received redirect response " + response.getStatusLine() + " but no location header"); } final String location = locationHeader.getValue(); if (this.log.isDebugEnabled()) { this.log.debug("Redirect requested to location '" + location + "'"); } final RequestConfig config = clientContext.getRequestConfig(); URI uri = createLocationURI(location); // rfc2616 demands the location value be a complete URI // Location = "Location" ":" absoluteURI try { if (!uri.isAbsolute()) { if (!config.isRelativeRedirectsAllowed()) { throw new ProtocolException("Relative redirect location '" + uri + "' not allowed"); } // Adjust location URI final HttpHost target = clientContext.getTargetHost(); Asserts.notNull(target, "Target host"); final URI requestURI = new URI(request.getRequestLine().getUri()); final URI absoluteRequestURI = URIUtils.rewriteURI(requestURI, target, false); uri = URIUtils.resolve(absoluteRequestURI, uri); } } catch (final URISyntaxException ex) { throw new ProtocolException(ex.getMessage(), ex); } RedirectLocations redirectLocations = (RedirectLocations) clientContext.getAttribute( HttpClientContext.REDIRECT_LOCATIONS); if (redirectLocations == null) { redirectLocations = new RedirectLocations(); context.setAttribute(HttpClientContext.REDIRECT_LOCATIONS, redirectLocations); } if (!config.isCircularRedirectsAllowed()) { if (redirectLocations.contains(uri)) { throw new CircularRedirectException("Circular redirect to '" + uri + "'"); } } redirectLocations.add(uri); return uri; } /** * @since 4.1 */ protected URI createLocationURI(final String location) throws ProtocolException { try { final URIBuilder b = new URIBuilder(new URI(location).normalize()); final String host = b.getHost(); if (host != null) { b.setHost(host.toLowerCase(Locale.US)); } final String path = b.getPath(); if (TextUtils.isEmpty(path)) { b.setPath("/"); } return b.build(); } catch (final URISyntaxException ex) { throw new ProtocolException("Invalid redirect URI: " + location, ex); } } /** * @since 4.2 */ protected boolean isRedirectable(final String method) { for (final String m: REDIRECT_METHODS) { if (m.equalsIgnoreCase(method)) { return true; } } return false; } public HttpUriRequest getRedirect( final HttpRequest request, final HttpResponse response, final HttpContext context) throws ProtocolException { final URI uri = getLocationURI(request, response, context); final String method = request.getRequestLine().getMethod(); if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) { return new HttpHead(uri); } else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) { return new HttpGet(uri); } else { final int status = response.getStatusLine().getStatusCode(); if (status == HttpStatus.SC_TEMPORARY_REDIRECT) { return RequestBuilder.copy(request).setUri(uri).build(); } else { return new HttpGet(uri); } } } } ././@LongLink0100644 0000000 0000000 00000000175 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/DefaultServiceUnavailableRetryStrategy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/DefaultServiceUnava0100644 0000000 0000000 00000005512 12301751710 032454 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.annotation.Immutable; import org.apache.http.client.ServiceUnavailableRetryStrategy; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Default implementation of the {@link ServiceUnavailableRetryStrategy} interface. * that retries 503 (Service Unavailable) responses for a fixed number of times * at a fixed interval. * * @since 4.2 */ @Immutable public class DefaultServiceUnavailableRetryStrategy implements ServiceUnavailableRetryStrategy { /** * Maximum number of allowed retries if the server responds with a HTTP code * in our retry code list. Default value is 1. */ private final int maxRetries; /** * Retry interval between subsequent requests, in milliseconds. Default * value is 1 second. */ private final long retryInterval; public DefaultServiceUnavailableRetryStrategy(final int maxRetries, final int retryInterval) { super(); Args.positive(maxRetries, "Max retries"); Args.positive(retryInterval, "Retry interval"); this.maxRetries = maxRetries; this.retryInterval = retryInterval; } public DefaultServiceUnavailableRetryStrategy() { this(1, 1000); } public boolean retryRequest(final HttpResponse response, final int executionCount, final HttpContext context) { return executionCount <= maxRetries && response.getStatusLine().getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE; } public long getRetryInterval() { return retryInterval; } } ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/DefaultUserTokenHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/DefaultUserTokenHan0100644 0000000 0000000 00000007653 12301751710 032437 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.security.Principal; import javax.net.ssl.SSLSession; import org.apache.http.HttpConnection; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthState; import org.apache.http.auth.Credentials; import org.apache.http.client.UserTokenHandler; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.protocol.HttpContext; /** * Default implementation of {@link UserTokenHandler}. This class will use * an instance of {@link Principal} as a state object for HTTP connections, * if it can be obtained from the given execution context. This helps ensure * persistent connections created with a particular user identity within * a particular security context can be reused by the same user only. *

* DefaultUserTokenHandler will use the user principle of connection * based authentication schemes such as NTLM or that of the SSL session * with the client authentication turned on. If both are unavailable, * null token will be returned. * * @since 4.0 */ @Immutable public class DefaultUserTokenHandler implements UserTokenHandler { public static final DefaultUserTokenHandler INSTANCE = new DefaultUserTokenHandler(); public Object getUserToken(final HttpContext context) { final HttpClientContext clientContext = HttpClientContext.adapt(context); Principal userPrincipal = null; final AuthState targetAuthState = clientContext.getTargetAuthState(); if (targetAuthState != null) { userPrincipal = getAuthPrincipal(targetAuthState); if (userPrincipal == null) { final AuthState proxyAuthState = clientContext.getProxyAuthState(); userPrincipal = getAuthPrincipal(proxyAuthState); } } if (userPrincipal == null) { final HttpConnection conn = clientContext.getConnection(); if (conn.isOpen() && conn instanceof ManagedHttpClientConnection) { final SSLSession sslsession = ((ManagedHttpClientConnection) conn).getSSLSession(); if (sslsession != null) { userPrincipal = sslsession.getLocalPrincipal(); } } } return userPrincipal; } private static Principal getAuthPrincipal(final AuthState authState) { final AuthScheme scheme = authState.getAuthScheme(); if (scheme != null && scheme.isComplete() && scheme.isConnectionBased()) { final Credentials creds = authState.getCredentials(); if (creds != null) { return creds.getUserPrincipal(); } } return null; } } ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/EntityEnclosingRequestWrapper.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/EntityEnclosingRequ0100644 0000000 0000000 00000006762 12301751711 032540 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.ProtocolException; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.entity.HttpEntityWrapper; import org.apache.http.protocol.HTTP; /** * A wrapper class for {@link HttpEntityEnclosingRequest}s that can * be used to change properties of the current request without * modifying the original object. *

* This class is also capable of resetting the request headers to * the state of the original request. * * @since 4.0 * * @deprecated (4.3) do not use. */ @Deprecated @NotThreadSafe // e.g. [gs]etEntity() public class EntityEnclosingRequestWrapper extends RequestWrapper implements HttpEntityEnclosingRequest { private HttpEntity entity; private boolean consumed; public EntityEnclosingRequestWrapper(final HttpEntityEnclosingRequest request) throws ProtocolException { super(request); setEntity(request.getEntity()); } public HttpEntity getEntity() { return this.entity; } public void setEntity(final HttpEntity entity) { this.entity = entity != null ? new EntityWrapper(entity) : null; this.consumed = false; } public boolean expectContinue() { final Header expect = getFirstHeader(HTTP.EXPECT_DIRECTIVE); return expect != null && HTTP.EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue()); } @Override public boolean isRepeatable() { return this.entity == null || this.entity.isRepeatable() || !this.consumed; } class EntityWrapper extends HttpEntityWrapper { EntityWrapper(final HttpEntity entity) { super(entity); } @Override public void consumeContent() throws IOException { consumed = true; super.consumeContent(); } @Override public InputStream getContent() throws IOException { consumed = true; return super.getContent(); } @Override public void writeTo(final OutputStream outstream) throws IOException { consumed = true; super.writeTo(outstream); } } } ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/FutureRequestExecutionMetrics.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/FutureRequestExecut0100644 0000000 0000000 00000011520 12301751711 032552 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.concurrent.atomic.AtomicLong; /** * Collection of different counters used to gather metrics for {@link FutureRequestExecutionService}. */ public final class FutureRequestExecutionMetrics { private final AtomicLong activeConnections = new AtomicLong(); private final AtomicLong scheduledConnections = new AtomicLong(); private final DurationCounter successfulConnections = new DurationCounter(); private final DurationCounter failedConnections = new DurationCounter(); private final DurationCounter requests = new DurationCounter(); private final DurationCounter tasks = new DurationCounter(); FutureRequestExecutionMetrics() { } AtomicLong getActiveConnections() { return activeConnections; } AtomicLong getScheduledConnections() { return scheduledConnections; } DurationCounter getSuccessfulConnections() { return successfulConnections; } DurationCounter getFailedConnections() { return failedConnections; } DurationCounter getRequests() { return requests; } DurationCounter getTasks() { return tasks; } public long getActiveConnectionCount() { return activeConnections.get(); } public long getScheduledConnectionCount() { return scheduledConnections.get(); } public long getSuccessfulConnectionCount() { return successfulConnections.count(); } public long getSuccessfulConnectionAverageDuration() { return successfulConnections.averageDuration(); } public long getFailedConnectionCount() { return failedConnections.count(); } public long getFailedConnectionAverageDuration() { return failedConnections.averageDuration(); } public long getRequestCount() { return requests.count(); } public long getRequestAverageDuration() { return requests.averageDuration(); } public long getTaskCount() { return tasks.count(); } public long getTaskAverageDuration() { return tasks.averageDuration(); } @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append("[activeConnections=").append(activeConnections) .append(", scheduledConnections=").append(scheduledConnections) .append(", successfulConnections=").append(successfulConnections) .append(", failedConnections=").append(failedConnections) .append(", requests=").append(requests) .append(", tasks=").append(tasks) .append("]"); return builder.toString(); } /** * A counter that can measure duration and number of events. */ static class DurationCounter { private final AtomicLong count = new AtomicLong(0); private final AtomicLong cumulativeDuration = new AtomicLong(0); public void increment(final long startTime) { count.incrementAndGet(); cumulativeDuration.addAndGet(System.currentTimeMillis() - startTime); } public long count() { return count.get(); } public long averageDuration() { final long counter = count.get(); return counter > 0 ? cumulativeDuration.get() / counter : 0; } @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append("[count=").append(count()) .append(", averageDuration=").append(averageDuration()) .append("]"); return builder.toString(); } } }././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/FutureRequestExecutionService.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/FutureRequestExecut0100644 0000000 0000000 00000012641 12301751711 032557 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.Closeable; import java.io.IOException; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.concurrent.FutureCallback; import org.apache.http.protocol.HttpContext; /** * HttpAsyncClientWithFuture wraps calls to execute with a {@link HttpRequestFutureTask} * and schedules them using the provided executor service. Scheduled calls may be cancelled. */ @ThreadSafe public class FutureRequestExecutionService implements Closeable { private final HttpClient httpclient; private final ExecutorService executorService; private final FutureRequestExecutionMetrics metrics = new FutureRequestExecutionMetrics(); private final AtomicBoolean closed = new AtomicBoolean(false); /** * Create a new FutureRequestExecutionService. * * @param httpclient * you should tune your httpclient instance to match your needs. You should * align the max number of connections in the pool and the number of threads * in the executor; it doesn't make sense to have more threads than connections * and if you have less connections than threads, the threads will just end up * blocking on getting a connection from the pool. * @param executorService * any executorService will do here. E.g. * {@link java.util.concurrent.Executors#newFixedThreadPool(int)} */ public FutureRequestExecutionService( final HttpClient httpclient, final ExecutorService executorService) { this.httpclient = httpclient; this.executorService = executorService; } /** * Schedule a request for execution. * * @param * * @param request * request to execute * @param responseHandler * handler that will process the response. * @return HttpAsyncClientFutureTask for the scheduled request. * @throws InterruptedException */ public HttpRequestFutureTask execute( final HttpUriRequest request, final HttpContext context, final ResponseHandler responseHandler) { return execute(request, context, responseHandler, null); } /** * Schedule a request for execution. * * @param * * @param request * request to execute * @param context * optional context; use null if not needed. * @param responseHandler * handler that will process the response. * @param callback * callback handler that will be called when the request is scheduled, * started, completed, failed, or cancelled. * @return HttpAsyncClientFutureTask for the scheduled request. * @throws InterruptedException */ public HttpRequestFutureTask execute( final HttpUriRequest request, final HttpContext context, final ResponseHandler responseHandler, final FutureCallback callback) { if(closed.get()) { throw new IllegalStateException("Close has been called on this httpclient instance."); } metrics.getScheduledConnections().incrementAndGet(); final HttpRequestTaskCallable callable = new HttpRequestTaskCallable( httpclient, request, context, responseHandler, callback, metrics); final HttpRequestFutureTask httpRequestFutureTask = new HttpRequestFutureTask( request, callable); executorService.execute(httpRequestFutureTask); return httpRequestFutureTask; } /** * @return metrics gathered for this instance. * @see FutureRequestExecutionMetrics */ public FutureRequestExecutionMetrics metrics() { return metrics; } public void close() throws IOException { closed.set(true); executorService.shutdownNow(); if (httpclient instanceof Closeable) { ((Closeable) httpclient).close(); } } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.j0100644 0000000 0000000 00000107242 12301751710 032374 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.Closeable; import java.net.ProxySelector; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import org.apache.http.ConnectionReuseStrategy; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequestInterceptor; import org.apache.http.HttpResponseInterceptor; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.client.AuthenticationStrategy; import org.apache.http.client.BackoffManager; import org.apache.http.client.ConnectionBackoffStrategy; import org.apache.http.client.CookieStore; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.RedirectStrategy; import org.apache.http.client.ServiceUnavailableRetryStrategy; import org.apache.http.client.UserTokenHandler; import org.apache.http.client.config.AuthSchemes; import org.apache.http.client.config.CookieSpecs; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.protocol.RequestAcceptEncoding; import org.apache.http.client.protocol.RequestAddCookies; import org.apache.http.client.protocol.RequestAuthCache; import org.apache.http.client.protocol.RequestClientConnControl; import org.apache.http.client.protocol.RequestDefaultHeaders; import org.apache.http.client.protocol.RequestExpectContinue; import org.apache.http.client.protocol.ResponseContentEncoding; import org.apache.http.client.protocol.ResponseProcessCookies; import org.apache.http.config.ConnectionConfig; import org.apache.http.config.Lookup; import org.apache.http.config.RegistryBuilder; import org.apache.http.config.SocketConfig; import org.apache.http.conn.ConnectionKeepAliveStrategy; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.conn.SchemePortResolver; import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.LayeredConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.conn.ssl.X509HostnameVerifier; import org.apache.http.cookie.CookieSpecProvider; import org.apache.http.impl.DefaultConnectionReuseStrategy; import org.apache.http.impl.NoConnectionReuseStrategy; import org.apache.http.impl.auth.BasicSchemeFactory; import org.apache.http.impl.auth.DigestSchemeFactory; import org.apache.http.impl.auth.KerberosSchemeFactory; import org.apache.http.impl.auth.NTLMSchemeFactory; import org.apache.http.impl.auth.SPNegoSchemeFactory; import org.apache.http.impl.conn.DefaultProxyRoutePlanner; import org.apache.http.impl.conn.DefaultRoutePlanner; import org.apache.http.impl.conn.DefaultSchemePortResolver; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.impl.conn.SystemDefaultRoutePlanner; import org.apache.http.impl.cookie.BestMatchSpecFactory; import org.apache.http.impl.cookie.BrowserCompatSpecFactory; import org.apache.http.impl.cookie.IgnoreSpecFactory; import org.apache.http.impl.cookie.NetscapeDraftSpecFactory; import org.apache.http.impl.cookie.RFC2109SpecFactory; import org.apache.http.impl.cookie.RFC2965SpecFactory; import org.apache.http.impl.execchain.BackoffStrategyExec; import org.apache.http.impl.execchain.ClientExecChain; import org.apache.http.impl.execchain.MainClientExec; import org.apache.http.impl.execchain.ProtocolExec; import org.apache.http.impl.execchain.RedirectExec; import org.apache.http.impl.execchain.RetryExec; import org.apache.http.impl.execchain.ServiceUnavailableRetryExec; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpProcessorBuilder; import org.apache.http.protocol.HttpRequestExecutor; import org.apache.http.protocol.RequestContent; import org.apache.http.protocol.RequestTargetHost; import org.apache.http.protocol.RequestUserAgent; import org.apache.http.util.TextUtils; import org.apache.http.util.VersionInfo; /** * Builder for {@link CloseableHttpClient} instances. *

* When a particular component is not explicitly this class will * use its default implementation. System properties will be taken * into account when configuring the default implementations when * {@link #useSystemProperties()} method is called prior to calling * {@link #build()}. *

    *
  • ssl.TrustManagerFactory.algorithm
  • *
  • javax.net.ssl.trustStoreType
  • *
  • javax.net.ssl.trustStore
  • *
  • javax.net.ssl.trustStoreProvider
  • *
  • javax.net.ssl.trustStorePassword
  • *
  • ssl.KeyManagerFactory.algorithm
  • *
  • javax.net.ssl.keyStoreType
  • *
  • javax.net.ssl.keyStore
  • *
  • javax.net.ssl.keyStoreProvider
  • *
  • javax.net.ssl.keyStorePassword
  • *
  • https.protocols
  • *
  • https.cipherSuites
  • *
  • http.proxyHost
  • *
  • http.proxyPort
  • *
  • http.nonProxyHosts
  • *
  • http.keepAlive
  • *
  • http.maxConnections
  • *
  • http.agent
  • *
*

* Please note that some settings used by this class can be mutually * exclusive and may not apply when building {@link CloseableHttpClient} * instances. * * @since 4.3 */ @NotThreadSafe public class HttpClientBuilder { private HttpRequestExecutor requestExec; private X509HostnameVerifier hostnameVerifier; private LayeredConnectionSocketFactory sslSocketFactory; private SSLContext sslcontext; private HttpClientConnectionManager connManager; private SchemePortResolver schemePortResolver; private ConnectionReuseStrategy reuseStrategy; private ConnectionKeepAliveStrategy keepAliveStrategy; private AuthenticationStrategy targetAuthStrategy; private AuthenticationStrategy proxyAuthStrategy; private UserTokenHandler userTokenHandler; private HttpProcessor httpprocessor; private LinkedList requestFirst; private LinkedList requestLast; private LinkedList responseFirst; private LinkedList responseLast; private HttpRequestRetryHandler retryHandler; private HttpRoutePlanner routePlanner; private RedirectStrategy redirectStrategy; private ConnectionBackoffStrategy connectionBackoffStrategy; private BackoffManager backoffManager; private ServiceUnavailableRetryStrategy serviceUnavailStrategy; private Lookup authSchemeRegistry; private Lookup cookieSpecRegistry; private CookieStore cookieStore; private CredentialsProvider credentialsProvider; private String userAgent; private HttpHost proxy; private Collection defaultHeaders; private SocketConfig defaultSocketConfig; private ConnectionConfig defaultConnectionConfig; private RequestConfig defaultRequestConfig; private boolean systemProperties; private boolean redirectHandlingDisabled; private boolean automaticRetriesDisabled; private boolean contentCompressionDisabled; private boolean cookieManagementDisabled; private boolean authCachingDisabled; private boolean connectionStateDisabled; private int maxConnTotal = 0; private int maxConnPerRoute = 0; private List closeables; static final String DEFAULT_USER_AGENT; static { final VersionInfo vi = VersionInfo.loadVersionInfo ("org.apache.http.client", HttpClientBuilder.class.getClassLoader()); final String release = (vi != null) ? vi.getRelease() : VersionInfo.UNAVAILABLE; DEFAULT_USER_AGENT = "Apache-HttpClient/" + release + " (java 1.5)"; } public static HttpClientBuilder create() { return new HttpClientBuilder(); } protected HttpClientBuilder() { super(); } /** * Assigns {@link HttpRequestExecutor} instance. */ public final HttpClientBuilder setRequestExecutor(final HttpRequestExecutor requestExec) { this.requestExec = requestExec; return this; } /** * Assigns {@link X509HostnameVerifier} instance. *

* Please note this value can be overridden by the {@link #setConnectionManager( * org.apache.http.conn.HttpClientConnectionManager)} and the {@link #setSSLSocketFactory( * org.apache.http.conn.socket.LayeredConnectionSocketFactory)} methods. */ public final HttpClientBuilder setHostnameVerifier(final X509HostnameVerifier hostnameVerifier) { this.hostnameVerifier = hostnameVerifier; return this; } /** * Assigns {@link SSLContext} instance. *

*

* Please note this value can be overridden by the {@link #setConnectionManager( * org.apache.http.conn.HttpClientConnectionManager)} and the {@link #setSSLSocketFactory( * org.apache.http.conn.socket.LayeredConnectionSocketFactory)} methods. */ public final HttpClientBuilder setSslcontext(final SSLContext sslcontext) { this.sslcontext = sslcontext; return this; } /** * Assigns {@link LayeredConnectionSocketFactory} instance. *

* Please note this value can be overridden by the {@link #setConnectionManager( * org.apache.http.conn.HttpClientConnectionManager)} method. */ public final HttpClientBuilder setSSLSocketFactory( final LayeredConnectionSocketFactory sslSocketFactory) { this.sslSocketFactory = sslSocketFactory; return this; } /** * Assigns maximum total connection value. *

* Please note this value can be overridden by the {@link #setConnectionManager( * org.apache.http.conn.HttpClientConnectionManager)} method. */ public final HttpClientBuilder setMaxConnTotal(final int maxConnTotal) { this.maxConnTotal = maxConnTotal; return this; } /** * Assigns maximum connection per route value. *

* Please note this value can be overridden by the {@link #setConnectionManager( * org.apache.http.conn.HttpClientConnectionManager)} method. */ public final HttpClientBuilder setMaxConnPerRoute(final int maxConnPerRoute) { this.maxConnPerRoute = maxConnPerRoute; return this; } /** * Assigns default {@link SocketConfig}. *

* Please note this value can be overridden by the {@link #setConnectionManager( * org.apache.http.conn.HttpClientConnectionManager)} method. */ public final HttpClientBuilder setDefaultSocketConfig(final SocketConfig config) { this.defaultSocketConfig = config; return this; } /** * Assigns default {@link ConnectionConfig}. *

* Please note this value can be overridden by the {@link #setConnectionManager( * org.apache.http.conn.HttpClientConnectionManager)} method. */ public final HttpClientBuilder setDefaultConnectionConfig(final ConnectionConfig config) { this.defaultConnectionConfig = config; return this; } /** * Assigns {@link HttpClientConnectionManager} instance. */ public final HttpClientBuilder setConnectionManager( final HttpClientConnectionManager connManager) { this.connManager = connManager; return this; } /** * Assigns {@link ConnectionReuseStrategy} instance. */ public final HttpClientBuilder setConnectionReuseStrategy( final ConnectionReuseStrategy reuseStrategy) { this.reuseStrategy = reuseStrategy; return this; } /** * Assigns {@link ConnectionKeepAliveStrategy} instance. */ public final HttpClientBuilder setKeepAliveStrategy( final ConnectionKeepAliveStrategy keepAliveStrategy) { this.keepAliveStrategy = keepAliveStrategy; return this; } /** * Assigns {@link AuthenticationStrategy} instance for proxy * authentication. */ public final HttpClientBuilder setTargetAuthenticationStrategy( final AuthenticationStrategy targetAuthStrategy) { this.targetAuthStrategy = targetAuthStrategy; return this; } /** * Assigns {@link AuthenticationStrategy} instance for target * host authentication. */ public final HttpClientBuilder setProxyAuthenticationStrategy( final AuthenticationStrategy proxyAuthStrategy) { this.proxyAuthStrategy = proxyAuthStrategy; return this; } /** * Assigns {@link UserTokenHandler} instance. *

* Please note this value can be overridden by the {@link #disableConnectionState()} * method. */ public final HttpClientBuilder setUserTokenHandler(final UserTokenHandler userTokenHandler) { this.userTokenHandler = userTokenHandler; return this; } /** * Disables connection state tracking. */ public final HttpClientBuilder disableConnectionState() { connectionStateDisabled = true; return this; } /** * Assigns {@link SchemePortResolver} instance. */ public final HttpClientBuilder setSchemePortResolver( final SchemePortResolver schemePortResolver) { this.schemePortResolver = schemePortResolver; return this; } /** * Assigns User-Agent value. *

* Please note this value can be overridden by the {@link #setHttpProcessor( * org.apache.http.protocol.HttpProcessor)} method. */ public final HttpClientBuilder setUserAgent(final String userAgent) { this.userAgent = userAgent; return this; } /** * Assigns default request header values. *

* Please note this value can be overridden by the {@link #setHttpProcessor( * org.apache.http.protocol.HttpProcessor)} method. */ public final HttpClientBuilder setDefaultHeaders(final Collection defaultHeaders) { this.defaultHeaders = defaultHeaders; return this; } /** * Adds this protocol interceptor to the head of the protocol processing list. *

* Please note this value can be overridden by the {@link #setHttpProcessor( * org.apache.http.protocol.HttpProcessor)} method. */ public final HttpClientBuilder addInterceptorFirst(final HttpResponseInterceptor itcp) { if (itcp == null) { return this; } if (responseFirst == null) { responseFirst = new LinkedList(); } responseFirst.addFirst(itcp); return this; } /** * Adds this protocol interceptor to the tail of the protocol processing list. *

* Please note this value can be overridden by the {@link #setHttpProcessor( * org.apache.http.protocol.HttpProcessor)} method. */ public final HttpClientBuilder addInterceptorLast(final HttpResponseInterceptor itcp) { if (itcp == null) { return this; } if (responseLast == null) { responseLast = new LinkedList(); } responseLast.addLast(itcp); return this; } /** * Adds this protocol interceptor to the head of the protocol processing list. *

* Please note this value can be overridden by the {@link #setHttpProcessor( * org.apache.http.protocol.HttpProcessor)} method. */ public final HttpClientBuilder addInterceptorFirst(final HttpRequestInterceptor itcp) { if (itcp == null) { return this; } if (requestFirst == null) { requestFirst = new LinkedList(); } requestFirst.addFirst(itcp); return this; } /** * Adds this protocol interceptor to the tail of the protocol processing list. *

* Please note this value can be overridden by the {@link #setHttpProcessor( * org.apache.http.protocol.HttpProcessor)} method. */ public final HttpClientBuilder addInterceptorLast(final HttpRequestInterceptor itcp) { if (itcp == null) { return this; } if (requestLast == null) { requestLast = new LinkedList(); } requestLast.addLast(itcp); return this; } /** * Disables state (cookie) management. *

* Please note this value can be overridden by the {@link #setHttpProcessor( * org.apache.http.protocol.HttpProcessor)} method. */ public final HttpClientBuilder disableCookieManagement() { this.cookieManagementDisabled = true; return this; } /** * Disables automatic content decompression. *

* Please note this value can be overridden by the {@link #setHttpProcessor( * org.apache.http.protocol.HttpProcessor)} method. */ public final HttpClientBuilder disableContentCompression() { contentCompressionDisabled = true; return this; } /** * Disables authentication scheme caching. *

* Please note this value can be overridden by the {@link #setHttpProcessor( * org.apache.http.protocol.HttpProcessor)} method. */ public final HttpClientBuilder disableAuthCaching() { this.authCachingDisabled = true; return this; } /** * Assigns {@link HttpProcessor} instance. */ public final HttpClientBuilder setHttpProcessor(final HttpProcessor httpprocessor) { this.httpprocessor = httpprocessor; return this; } /** * Assigns {@link HttpRequestRetryHandler} instance. *

* Please note this value can be overridden by the {@link #disableAutomaticRetries()} * method. */ public final HttpClientBuilder setRetryHandler(final HttpRequestRetryHandler retryHandler) { this.retryHandler = retryHandler; return this; } /** * Disables automatic request recovery and re-execution. */ public final HttpClientBuilder disableAutomaticRetries() { automaticRetriesDisabled = true; return this; } /** * Assigns default proxy value. *

* Please note this value can be overridden by the {@link #setRoutePlanner( * org.apache.http.conn.routing.HttpRoutePlanner)} method. */ public final HttpClientBuilder setProxy(final HttpHost proxy) { this.proxy = proxy; return this; } /** * Assigns {@link HttpRoutePlanner} instance. */ public final HttpClientBuilder setRoutePlanner(final HttpRoutePlanner routePlanner) { this.routePlanner = routePlanner; return this; } /** * Assigns {@link RedirectStrategy} instance. *

* Please note this value can be overridden by the {@link #disableRedirectHandling()} * method. ` */ public final HttpClientBuilder setRedirectStrategy(final RedirectStrategy redirectStrategy) { this.redirectStrategy = redirectStrategy; return this; } /** * Disables automatic redirect handling. */ public final HttpClientBuilder disableRedirectHandling() { redirectHandlingDisabled = true; return this; } /** * Assigns {@link ConnectionBackoffStrategy} instance. */ public final HttpClientBuilder setConnectionBackoffStrategy( final ConnectionBackoffStrategy connectionBackoffStrategy) { this.connectionBackoffStrategy = connectionBackoffStrategy; return this; } /** * Assigns {@link BackoffManager} instance. */ public final HttpClientBuilder setBackoffManager(final BackoffManager backoffManager) { this.backoffManager = backoffManager; return this; } /** * Assigns {@link ServiceUnavailableRetryStrategy} instance. */ public final HttpClientBuilder setServiceUnavailableRetryStrategy( final ServiceUnavailableRetryStrategy serviceUnavailStrategy) { this.serviceUnavailStrategy = serviceUnavailStrategy; return this; } /** * Assigns default {@link CookieStore} instance which will be used for * request execution if not explicitly set in the client execution context. */ public final HttpClientBuilder setDefaultCookieStore(final CookieStore cookieStore) { this.cookieStore = cookieStore; return this; } /** * Assigns default {@link CredentialsProvider} instance which will be used * for request execution if not explicitly set in the client execution * context. */ public final HttpClientBuilder setDefaultCredentialsProvider( final CredentialsProvider credentialsProvider) { this.credentialsProvider = credentialsProvider; return this; } /** * Assigns default {@link org.apache.http.auth.AuthScheme} registry which will * be used for request execution if not explicitly set in the client execution * context. */ public final HttpClientBuilder setDefaultAuthSchemeRegistry( final Lookup authSchemeRegistry) { this.authSchemeRegistry = authSchemeRegistry; return this; } /** * Assigns default {@link org.apache.http.cookie.CookieSpec} registry which will * be used for request execution if not explicitly set in the client execution * context. */ public final HttpClientBuilder setDefaultCookieSpecRegistry( final Lookup cookieSpecRegistry) { this.cookieSpecRegistry = cookieSpecRegistry; return this; } /** * Assigns default {@link RequestConfig} instance which will be used * for request execution if not explicitly set in the client execution * context. */ public final HttpClientBuilder setDefaultRequestConfig(final RequestConfig config) { this.defaultRequestConfig = config; return this; } /** * Use system properties when creating and configuring default * implementations. */ public final HttpClientBuilder useSystemProperties() { systemProperties = true; return this; } /** * For internal use. */ protected ClientExecChain decorateMainExec(final ClientExecChain mainExec) { return mainExec; } /** * For internal use. */ protected ClientExecChain decorateProtocolExec(final ClientExecChain protocolExec) { return protocolExec; } /** * For internal use. */ protected void addCloseable(final Closeable closeable) { if (closeable == null) { return; } if (closeables == null) { closeables = new ArrayList(); } closeables.add(closeable); } private static String[] split(final String s) { if (TextUtils.isBlank(s)) { return null; } return s.split(" *, *"); } public CloseableHttpClient build() { // Create main request executor HttpRequestExecutor requestExec = this.requestExec; if (requestExec == null) { requestExec = new HttpRequestExecutor(); } HttpClientConnectionManager connManager = this.connManager; if (connManager == null) { LayeredConnectionSocketFactory sslSocketFactory = this.sslSocketFactory; if (sslSocketFactory == null) { final String[] supportedProtocols = systemProperties ? split( System.getProperty("https.protocols")) : null; final String[] supportedCipherSuites = systemProperties ? split( System.getProperty("https.cipherSuites")) : null; X509HostnameVerifier hostnameVerifier = this.hostnameVerifier; if (hostnameVerifier == null) { hostnameVerifier = SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; } if (sslcontext != null) { sslSocketFactory = new SSLConnectionSocketFactory( sslcontext, supportedProtocols, supportedCipherSuites, hostnameVerifier); } else { if (systemProperties) { sslSocketFactory = new SSLConnectionSocketFactory( (SSLSocketFactory) SSLSocketFactory.getDefault(), supportedProtocols, supportedCipherSuites, hostnameVerifier); } else { sslSocketFactory = new SSLConnectionSocketFactory( SSLContexts.createDefault(), hostnameVerifier); } } } @SuppressWarnings("resource") final PoolingHttpClientConnectionManager poolingmgr = new PoolingHttpClientConnectionManager( RegistryBuilder.create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", sslSocketFactory) .build()); if (defaultSocketConfig != null) { poolingmgr.setDefaultSocketConfig(defaultSocketConfig); } if (defaultConnectionConfig != null) { poolingmgr.setDefaultConnectionConfig(defaultConnectionConfig); } if (systemProperties) { String s = System.getProperty("http.keepAlive", "true"); if ("true".equalsIgnoreCase(s)) { s = System.getProperty("http.maxConnections", "5"); final int max = Integer.parseInt(s); poolingmgr.setDefaultMaxPerRoute(max); poolingmgr.setMaxTotal(2 * max); } } if (maxConnTotal > 0) { poolingmgr.setMaxTotal(maxConnTotal); } if (maxConnPerRoute > 0) { poolingmgr.setDefaultMaxPerRoute(maxConnPerRoute); } connManager = poolingmgr; } ConnectionReuseStrategy reuseStrategy = this.reuseStrategy; if (reuseStrategy == null) { if (systemProperties) { final String s = System.getProperty("http.keepAlive", "true"); if ("true".equalsIgnoreCase(s)) { reuseStrategy = DefaultConnectionReuseStrategy.INSTANCE; } else { reuseStrategy = NoConnectionReuseStrategy.INSTANCE; } } else { reuseStrategy = DefaultConnectionReuseStrategy.INSTANCE; } } ConnectionKeepAliveStrategy keepAliveStrategy = this.keepAliveStrategy; if (keepAliveStrategy == null) { keepAliveStrategy = DefaultConnectionKeepAliveStrategy.INSTANCE; } AuthenticationStrategy targetAuthStrategy = this.targetAuthStrategy; if (targetAuthStrategy == null) { targetAuthStrategy = TargetAuthenticationStrategy.INSTANCE; } AuthenticationStrategy proxyAuthStrategy = this.proxyAuthStrategy; if (proxyAuthStrategy == null) { proxyAuthStrategy = ProxyAuthenticationStrategy.INSTANCE; } UserTokenHandler userTokenHandler = this.userTokenHandler; if (userTokenHandler == null) { if (!connectionStateDisabled) { userTokenHandler = DefaultUserTokenHandler.INSTANCE; } else { userTokenHandler = NoopUserTokenHandler.INSTANCE; } } ClientExecChain execChain = new MainClientExec( requestExec, connManager, reuseStrategy, keepAliveStrategy, targetAuthStrategy, proxyAuthStrategy, userTokenHandler); execChain = decorateMainExec(execChain); HttpProcessor httpprocessor = this.httpprocessor; if (httpprocessor == null) { String userAgent = this.userAgent; if (userAgent == null) { if (systemProperties) { userAgent = System.getProperty("http.agent"); } if (userAgent == null) { userAgent = DEFAULT_USER_AGENT; } } final HttpProcessorBuilder b = HttpProcessorBuilder.create(); if (requestFirst != null) { for (final HttpRequestInterceptor i: requestFirst) { b.addFirst(i); } } if (responseFirst != null) { for (final HttpResponseInterceptor i: responseFirst) { b.addFirst(i); } } b.addAll( new RequestDefaultHeaders(defaultHeaders), new RequestContent(), new RequestTargetHost(), new RequestClientConnControl(), new RequestUserAgent(userAgent), new RequestExpectContinue()); if (!cookieManagementDisabled) { b.add(new RequestAddCookies()); } if (!contentCompressionDisabled) { b.add(new RequestAcceptEncoding()); } if (!authCachingDisabled) { b.add(new RequestAuthCache()); } if (!cookieManagementDisabled) { b.add(new ResponseProcessCookies()); } if (!contentCompressionDisabled) { b.add(new ResponseContentEncoding()); } if (requestLast != null) { for (final HttpRequestInterceptor i: requestLast) { b.addLast(i); } } if (responseLast != null) { for (final HttpResponseInterceptor i: responseLast) { b.addLast(i); } } httpprocessor = b.build(); } execChain = new ProtocolExec(execChain, httpprocessor); execChain = decorateProtocolExec(execChain); // Add request retry executor, if not disabled if (!automaticRetriesDisabled) { HttpRequestRetryHandler retryHandler = this.retryHandler; if (retryHandler == null) { retryHandler = DefaultHttpRequestRetryHandler.INSTANCE; } execChain = new RetryExec(execChain, retryHandler); } HttpRoutePlanner routePlanner = this.routePlanner; if (routePlanner == null) { SchemePortResolver schemePortResolver = this.schemePortResolver; if (schemePortResolver == null) { schemePortResolver = DefaultSchemePortResolver.INSTANCE; } if (proxy != null) { routePlanner = new DefaultProxyRoutePlanner(proxy, schemePortResolver); } else if (systemProperties) { routePlanner = new SystemDefaultRoutePlanner( schemePortResolver, ProxySelector.getDefault()); } else { routePlanner = new DefaultRoutePlanner(schemePortResolver); } } // Add redirect executor, if not disabled if (!redirectHandlingDisabled) { RedirectStrategy redirectStrategy = this.redirectStrategy; if (redirectStrategy == null) { redirectStrategy = DefaultRedirectStrategy.INSTANCE; } execChain = new RedirectExec(execChain, routePlanner, redirectStrategy); } // Optionally, add service unavailable retry executor final ServiceUnavailableRetryStrategy serviceUnavailStrategy = this.serviceUnavailStrategy; if (serviceUnavailStrategy != null) { execChain = new ServiceUnavailableRetryExec(execChain, serviceUnavailStrategy); } // Optionally, add connection back-off executor final BackoffManager backoffManager = this.backoffManager; final ConnectionBackoffStrategy connectionBackoffStrategy = this.connectionBackoffStrategy; if (backoffManager != null && connectionBackoffStrategy != null) { execChain = new BackoffStrategyExec(execChain, connectionBackoffStrategy, backoffManager); } Lookup authSchemeRegistry = this.authSchemeRegistry; if (authSchemeRegistry == null) { authSchemeRegistry = RegistryBuilder.create() .register(AuthSchemes.BASIC, new BasicSchemeFactory()) .register(AuthSchemes.DIGEST, new DigestSchemeFactory()) .register(AuthSchemes.NTLM, new NTLMSchemeFactory()) .register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory()) .register(AuthSchemes.KERBEROS, new KerberosSchemeFactory()) .build(); } Lookup cookieSpecRegistry = this.cookieSpecRegistry; if (cookieSpecRegistry == null) { cookieSpecRegistry = RegistryBuilder.create() .register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory()) .register(CookieSpecs.STANDARD, new RFC2965SpecFactory()) .register(CookieSpecs.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory()) .register(CookieSpecs.NETSCAPE, new NetscapeDraftSpecFactory()) .register(CookieSpecs.IGNORE_COOKIES, new IgnoreSpecFactory()) .register("rfc2109", new RFC2109SpecFactory()) .register("rfc2965", new RFC2965SpecFactory()) .build(); } CookieStore defaultCookieStore = this.cookieStore; if (defaultCookieStore == null) { defaultCookieStore = new BasicCookieStore(); } CredentialsProvider defaultCredentialsProvider = this.credentialsProvider; if (defaultCredentialsProvider == null) { if (systemProperties) { defaultCredentialsProvider = new SystemDefaultCredentialsProvider(); } else { defaultCredentialsProvider = new BasicCredentialsProvider(); } } return new InternalHttpClient( execChain, connManager, routePlanner, cookieSpecRegistry, authSchemeRegistry, defaultCookieStore, defaultCredentialsProvider, defaultRequestConfig != null ? defaultRequestConfig : RequestConfig.DEFAULT, closeables != null ? new ArrayList(closeables) : null); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/HttpClients.java0100644 0000000 0000000 00000005416 12301751711 031741 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.annotation.Immutable; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; /** * Factory methods for {@link CloseableHttpClient} instances. * @since 4.3 */ @Immutable public class HttpClients { private HttpClients() { super(); } /** * Creates builder object for construction of custom * {@link CloseableHttpClient} instances. */ public static HttpClientBuilder custom() { return HttpClientBuilder.create(); } /** * Creates {@link CloseableHttpClient} instance with default * configuration. */ public static CloseableHttpClient createDefault() { return HttpClientBuilder.create().build(); } /** * Creates {@link CloseableHttpClient} instance with default * configuration based on ssytem properties. */ public static CloseableHttpClient createSystem() { return HttpClientBuilder.create().useSystemProperties().build(); } /** * Creates {@link CloseableHttpClient} instance that implements * the most basic HTTP protocol support. */ public static CloseableHttpClient createMinimal() { return new MinimalHttpClient(new PoolingHttpClientConnectionManager()); } /** * Creates {@link CloseableHttpClient} instance that implements * the most basic HTTP protocol support. */ public static CloseableHttpClient createMinimal(final HttpClientConnectionManager connManager) { return new MinimalHttpClient(connManager); } } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/HttpRequestFutureTask.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/HttpRequestFutureTa0100644 0000000 0000000 00000006743 12301751711 032534 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.concurrent.FutureTask; import org.apache.http.client.methods.HttpUriRequest; /** * FutureTask implementation that wraps a HttpAsyncClientCallable and exposes various task * specific metrics. * * @param */ public class HttpRequestFutureTask extends FutureTask { private final HttpUriRequest request; private final HttpRequestTaskCallable callable; public HttpRequestFutureTask( final HttpUriRequest request, final HttpRequestTaskCallable httpCallable) { super(httpCallable); this.request = request; this.callable = httpCallable; } /* * (non-Javadoc) * @see java.util.concurrent.FutureTask#cancel(boolean) */ @Override public boolean cancel(final boolean mayInterruptIfRunning) { callable.cancel(); if (mayInterruptIfRunning) { request.abort(); } return super.cancel(mayInterruptIfRunning); } /** * @return the time in millis the task was scheduled. */ public long scheduledTime() { return callable.getScheduled(); } /** * @return the time in millis the task was started. */ public long startedTime() { return callable.getStarted(); } /** * @return the time in millis the task was finished/cancelled. */ public long endedTime() { if (isDone()) { return callable.getEnded(); } else { throw new IllegalStateException("Task is not done yet"); } } /** * @return the time in millis it took to make the request (excluding the time it was * scheduled to be executed). */ public long requestDuration() { if (isDone()) { return endedTime() - startedTime(); } else { throw new IllegalStateException("Task is not done yet"); } } /** * @return the time in millis it took to execute the task from the moment it was scheduled. */ public long taskDuration() { if (isDone()) { return endedTime() - scheduledTime(); } else { throw new IllegalStateException("Task is not done yet"); } } @Override public String toString() { return request.getRequestLine().getUri(); } }././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/HttpRequestTaskCallable.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/HttpRequestTaskCall0100644 0000000 0000000 00000010324 12301751711 032461 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.concurrent.FutureCallback; import org.apache.http.protocol.HttpContext; class HttpRequestTaskCallable implements Callable { private final HttpUriRequest request; private final HttpClient httpclient; private final AtomicBoolean cancelled = new AtomicBoolean(false); private final long scheduled = System.currentTimeMillis(); private long started = -1; private long ended = -1; private final HttpContext context; private final ResponseHandler responseHandler; private final FutureCallback callback; private final FutureRequestExecutionMetrics metrics; HttpRequestTaskCallable( final HttpClient httpClient, final HttpUriRequest request, final HttpContext context, final ResponseHandler responseHandler, final FutureCallback callback, final FutureRequestExecutionMetrics metrics) { this.httpclient = httpClient; this.responseHandler = responseHandler; this.request = request; this.context = context; this.callback = callback; this.metrics = metrics; } public long getScheduled() { return scheduled; } public long getStarted() { return started; } public long getEnded() { return ended; } public V call() throws Exception { if (!cancelled.get()) { try { metrics.getActiveConnections().incrementAndGet(); started = System.currentTimeMillis(); try { metrics.getScheduledConnections().decrementAndGet(); final V result = httpclient.execute(request, responseHandler, context); ended = System.currentTimeMillis(); metrics.getSuccessfulConnections().increment(started); if (callback != null) { callback.completed(result); } return result; } catch (final Exception e) { metrics.getFailedConnections().increment(started); ended = System.currentTimeMillis(); if (callback != null) { callback.failed(e); } throw e; } } finally { metrics.getRequests().increment(started); metrics.getTasks().increment(started); metrics.getActiveConnections().decrementAndGet(); } } else { throw new IllegalStateException("call has been cancelled for request " + request.getURI()); } } public void cancel() { cancelled.set(true); if (callback != null) { callback.cancelled(); } } }././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/InternalHttpClient.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/InternalHttpClient.0100644 0000000 0000000 00000023337 12301751710 032412 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.Closeable; import java.io.IOException; import java.util.List; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.annotation.ThreadSafe; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.auth.AuthState; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CookieStore; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.Configurable; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.params.HttpClientParamConfig; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.Lookup; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.ClientConnectionRequest; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.conn.ManagedClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.cookie.CookieSpecProvider; import org.apache.http.impl.execchain.ClientExecChain; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpParamsNames; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.Asserts; /** * Internal class. * * @since 4.3 */ @ThreadSafe @SuppressWarnings("deprecation") class InternalHttpClient extends CloseableHttpClient { private final Log log = LogFactory.getLog(getClass()); private final ClientExecChain execChain; private final HttpClientConnectionManager connManager; private final HttpRoutePlanner routePlanner; private final Lookup cookieSpecRegistry; private final Lookup authSchemeRegistry; private final CookieStore cookieStore; private final CredentialsProvider credentialsProvider; private final RequestConfig defaultConfig; private final List closeables; public InternalHttpClient( final ClientExecChain execChain, final HttpClientConnectionManager connManager, final HttpRoutePlanner routePlanner, final Lookup cookieSpecRegistry, final Lookup authSchemeRegistry, final CookieStore cookieStore, final CredentialsProvider credentialsProvider, final RequestConfig defaultConfig, final List closeables) { super(); Args.notNull(execChain, "HTTP client exec chain"); Args.notNull(connManager, "HTTP connection manager"); Args.notNull(routePlanner, "HTTP route planner"); this.execChain = execChain; this.connManager = connManager; this.routePlanner = routePlanner; this.cookieSpecRegistry = cookieSpecRegistry; this.authSchemeRegistry = authSchemeRegistry; this.cookieStore = cookieStore; this.credentialsProvider = credentialsProvider; this.defaultConfig = defaultConfig; this.closeables = closeables; } private HttpRoute determineRoute( final HttpHost target, final HttpRequest request, final HttpContext context) throws HttpException { HttpHost host = target; if (host == null) { host = (HttpHost) request.getParams().getParameter(ClientPNames.DEFAULT_HOST); } Asserts.notNull(host, "Target host"); return this.routePlanner.determineRoute(host, request, context); } private void setupContext(final HttpClientContext context) { if (context.getAttribute(HttpClientContext.TARGET_AUTH_STATE) == null) { context.setAttribute(HttpClientContext.TARGET_AUTH_STATE, new AuthState()); } if (context.getAttribute(HttpClientContext.PROXY_AUTH_STATE) == null) { context.setAttribute(HttpClientContext.PROXY_AUTH_STATE, new AuthState()); } if (context.getAttribute(HttpClientContext.AUTHSCHEME_REGISTRY) == null) { context.setAttribute(HttpClientContext.AUTHSCHEME_REGISTRY, this.authSchemeRegistry); } if (context.getAttribute(HttpClientContext.COOKIESPEC_REGISTRY) == null) { context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); } if (context.getAttribute(HttpClientContext.COOKIE_STORE) == null) { context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); } if (context.getAttribute(HttpClientContext.CREDS_PROVIDER) == null) { context.setAttribute(HttpClientContext.CREDS_PROVIDER, this.credentialsProvider); } if (context.getAttribute(HttpClientContext.REQUEST_CONFIG) == null) { context.setAttribute(HttpClientContext.REQUEST_CONFIG, this.defaultConfig); } } @Override protected CloseableHttpResponse doExecute( final HttpHost target, final HttpRequest request, final HttpContext context) throws IOException, ClientProtocolException { Args.notNull(request, "HTTP request"); HttpExecutionAware execAware = null; if (request instanceof HttpExecutionAware) { execAware = (HttpExecutionAware) request; } try { final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(request); final HttpClientContext localcontext = HttpClientContext.adapt( context != null ? context : new BasicHttpContext()); RequestConfig config = null; if (request instanceof Configurable) { config = ((Configurable) request).getConfig(); } if (config == null) { final HttpParams params = request.getParams(); if (params instanceof HttpParamsNames) { if (!((HttpParamsNames) params).getNames().isEmpty()) { config = HttpClientParamConfig.getRequestConfig(params); } } else { config = HttpClientParamConfig.getRequestConfig(params); } } if (config != null) { localcontext.setRequestConfig(config); } setupContext(localcontext); final HttpRoute route = determineRoute(target, wrapper, localcontext); return this.execChain.execute(route, wrapper, localcontext, execAware); } catch (final HttpException httpException) { throw new ClientProtocolException(httpException); } } public void close() { this.connManager.shutdown(); if (this.closeables != null) { for (final Closeable closeable: this.closeables) { try { closeable.close(); } catch (final IOException ex) { this.log.error(ex.getMessage(), ex); } } } } public HttpParams getParams() { throw new UnsupportedOperationException(); } public ClientConnectionManager getConnectionManager() { return new ClientConnectionManager() { public void shutdown() { connManager.shutdown(); } public ClientConnectionRequest requestConnection( final HttpRoute route, final Object state) { throw new UnsupportedOperationException(); } public void releaseConnection( final ManagedClientConnection conn, final long validDuration, final TimeUnit timeUnit) { throw new UnsupportedOperationException(); } public SchemeRegistry getSchemeRegistry() { throw new UnsupportedOperationException(); } public void closeIdleConnections(final long idletime, final TimeUnit tunit) { connManager.closeIdleConnections(idletime, tunit); } public void closeExpiredConnections() { connManager.closeExpiredConnections(); } }; } } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/LaxRedirectStrategy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/LaxRedirectStrategy0100644 0000000 0000000 00000004266 12301751710 032512 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.annotation.Immutable; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpPost; /** * Lax {@link org.apache.http.client.RedirectStrategy} implementation * that automatically redirects all HEAD, GET and POST requests. * This strategy relaxes restrictions on automatic redirection of * POST methods imposed by the HTTP specification. * * @since 4.2 */ @Immutable public class LaxRedirectStrategy extends DefaultRedirectStrategy { /** * Redirectable methods. */ private static final String[] REDIRECT_METHODS = new String[] { HttpGet.METHOD_NAME, HttpPost.METHOD_NAME, HttpHead.METHOD_NAME }; @Override protected boolean isRedirectable(final String method) { for (final String m: REDIRECT_METHODS) { if (m.equalsIgnoreCase(method)) { return true; } } return false; } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/MinimalHttpClient.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/MinimalHttpClient.j0100644 0000000 0000000 00000013276 12301751710 032377 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.IOException; import java.util.concurrent.TimeUnit; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.Configurable; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.ClientConnectionRequest; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.conn.ManagedClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.impl.DefaultConnectionReuseStrategy; import org.apache.http.impl.execchain.MinimalClientExec; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestExecutor; import org.apache.http.util.Args; /** * Internal class. * * @since 4.3 */ @ThreadSafe @SuppressWarnings("deprecation") class MinimalHttpClient extends CloseableHttpClient { private final HttpClientConnectionManager connManager; private final MinimalClientExec requestExecutor; private final HttpParams params; public MinimalHttpClient( final HttpClientConnectionManager connManager) { super(); this.connManager = Args.notNull(connManager, "HTTP connection manager"); this.requestExecutor = new MinimalClientExec( new HttpRequestExecutor(), connManager, DefaultConnectionReuseStrategy.INSTANCE, DefaultConnectionKeepAliveStrategy.INSTANCE); this.params = new BasicHttpParams(); } @Override protected CloseableHttpResponse doExecute( final HttpHost target, final HttpRequest request, final HttpContext context) throws IOException, ClientProtocolException { Args.notNull(target, "Target host"); Args.notNull(request, "HTTP request"); HttpExecutionAware execAware = null; if (request instanceof HttpExecutionAware) { execAware = (HttpExecutionAware) request; } try { final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(request); final HttpClientContext localcontext = HttpClientContext.adapt( context != null ? context : new BasicHttpContext()); final HttpRoute route = new HttpRoute(target); RequestConfig config = null; if (request instanceof Configurable) { config = ((Configurable) request).getConfig(); } if (config != null) { localcontext.setRequestConfig(config); } return this.requestExecutor.execute(route, wrapper, localcontext, execAware); } catch (final HttpException httpException) { throw new ClientProtocolException(httpException); } } public HttpParams getParams() { return this.params; } public void close() { this.connManager.shutdown(); } public ClientConnectionManager getConnectionManager() { return new ClientConnectionManager() { public void shutdown() { connManager.shutdown(); } public ClientConnectionRequest requestConnection( final HttpRoute route, final Object state) { throw new UnsupportedOperationException(); } public void releaseConnection( final ManagedClientConnection conn, final long validDuration, final TimeUnit timeUnit) { throw new UnsupportedOperationException(); } public SchemeRegistry getSchemeRegistry() { throw new UnsupportedOperationException(); } public void closeIdleConnections(final long idletime, final TimeUnit tunit) { connManager.closeIdleConnections(idletime, tunit); } public void closeExpiredConnections() { connManager.closeExpiredConnections(); } }; } } ././@LongLink0100644 0000000 0000000 00000000153 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/NoopUserTokenHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/NoopUserTokenHandle0100644 0000000 0000000 00000003277 12301751710 032451 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.annotation.Immutable; import org.apache.http.client.UserTokenHandler; import org.apache.http.protocol.HttpContext; /** * Noop implementation of {@link UserTokenHandler} that always returns null. * * @since 4.3 */ @Immutable public class NoopUserTokenHandler implements UserTokenHandler { public static final NoopUserTokenHandler INSTANCE = new NoopUserTokenHandler(); public Object getUserToken(final HttpContext context) { return null; } } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/NullBackoffStrategy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/NullBackoffStrategy0100644 0000000 0000000 00000003246 12301751711 032470 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.HttpResponse; import org.apache.http.client.ConnectionBackoffStrategy; /** * This is a {@link ConnectionBackoffStrategy} that never backs off, * for compatibility with existing behavior. * * @since 4.2 */ public class NullBackoffStrategy implements ConnectionBackoffStrategy { public boolean shouldBackoff(final Throwable t) { return false; } public boolean shouldBackoff(final HttpResponse resp) { return false; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/package-info.java0100644 0000000 0000000 00000003654 12301751710 032025 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Default HTTP client implementation. *

* The usual execution flow can be demonstrated by the code snippet below: *

 * CloseableHttpClient httpclient = HttpClients.createDefault();
 * try {
 *      HttpGet httpGet = new HttpGet("http://targethost/homepage");
 *      CloseableHttpResponse response = httpclient.execute(httpGet);
 *      try {
 *          System.out.println(response.getStatusLine());
 *          HttpEntity entity = response.getEntity();
 *          // do something useful with the response body
 *          // and ensure it is fully consumed
 *          EntityUtils.consume(entity);
 *      } finally {
 *          response.close();
 *      }
 * } finally {
 *      httpclient.close();
 * }
 * 
*/ package org.apache.http.impl.client; ././@LongLink0100644 0000000 0000000 00000000162 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/ProxyAuthenticationStrategy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/ProxyAuthentication0100644 0000000 0000000 00000003755 12301751711 032605 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.Collection; import org.apache.http.HttpStatus; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AUTH; import org.apache.http.client.config.RequestConfig; /** * Default {@link org.apache.http.client.AuthenticationStrategy} implementation * for proxy host authentication. * * @since 4.2 */ @Immutable public class ProxyAuthenticationStrategy extends AuthenticationStrategyImpl { public static final ProxyAuthenticationStrategy INSTANCE = new ProxyAuthenticationStrategy(); public ProxyAuthenticationStrategy() { super(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED, AUTH.PROXY_AUTH); } @Override Collection getPreferredAuthSchemes(final RequestConfig config) { return config.getProxyPreferredAuthSchemes(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/ProxyClient.java0100644 0000000 0000000 00000024657 12301751710 031767 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.IOException; import java.net.Socket; import org.apache.http.ConnectionReuseStrategy; import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthSchemeRegistry; import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthState; import org.apache.http.auth.Credentials; import org.apache.http.client.config.AuthSchemes; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.params.HttpClientParamConfig; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.protocol.RequestClientConnControl; import org.apache.http.config.ConnectionConfig; import org.apache.http.conn.HttpConnectionFactory; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.RouteInfo.LayerType; import org.apache.http.conn.routing.RouteInfo.TunnelType; import org.apache.http.entity.BufferedHttpEntity; import org.apache.http.impl.DefaultConnectionReuseStrategy; import org.apache.http.impl.auth.BasicSchemeFactory; import org.apache.http.impl.auth.DigestSchemeFactory; import org.apache.http.impl.auth.HttpAuthenticator; import org.apache.http.impl.auth.KerberosSchemeFactory; import org.apache.http.impl.auth.NTLMSchemeFactory; import org.apache.http.impl.auth.SPNegoSchemeFactory; import org.apache.http.impl.conn.ManagedHttpClientConnectionFactory; import org.apache.http.impl.execchain.TunnelRefusedException; import org.apache.http.message.BasicHttpRequest; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpParamConfig; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpCoreContext; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpRequestExecutor; import org.apache.http.protocol.ImmutableHttpProcessor; import org.apache.http.protocol.RequestTargetHost; import org.apache.http.protocol.RequestUserAgent; import org.apache.http.util.Args; import org.apache.http.util.EntityUtils; /** * ProxyClient can be used to establish a tunnel via an HTTP proxy. */ @SuppressWarnings("deprecation") public class ProxyClient { private final HttpConnectionFactory connFactory; private final ConnectionConfig connectionConfig; private final RequestConfig requestConfig; private final HttpProcessor httpProcessor; private final HttpRequestExecutor requestExec; private final ProxyAuthenticationStrategy proxyAuthStrategy; private final HttpAuthenticator authenticator; private final AuthState proxyAuthState; private final AuthSchemeRegistry authSchemeRegistry; private final ConnectionReuseStrategy reuseStrategy; /** * @since 4.3 */ public ProxyClient( final HttpConnectionFactory connFactory, final ConnectionConfig connectionConfig, final RequestConfig requestConfig) { super(); this.connFactory = connFactory != null ? connFactory : ManagedHttpClientConnectionFactory.INSTANCE; this.connectionConfig = connectionConfig != null ? connectionConfig : ConnectionConfig.DEFAULT; this.requestConfig = requestConfig != null ? requestConfig : RequestConfig.DEFAULT; this.httpProcessor = new ImmutableHttpProcessor( new RequestTargetHost(), new RequestClientConnControl(), new RequestUserAgent()); this.requestExec = new HttpRequestExecutor(); this.proxyAuthStrategy = new ProxyAuthenticationStrategy(); this.authenticator = new HttpAuthenticator(); this.proxyAuthState = new AuthState(); this.authSchemeRegistry = new AuthSchemeRegistry(); this.authSchemeRegistry.register(AuthSchemes.BASIC, new BasicSchemeFactory()); this.authSchemeRegistry.register(AuthSchemes.DIGEST, new DigestSchemeFactory()); this.authSchemeRegistry.register(AuthSchemes.NTLM, new NTLMSchemeFactory()); this.authSchemeRegistry.register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory()); this.authSchemeRegistry.register(AuthSchemes.KERBEROS, new KerberosSchemeFactory()); this.reuseStrategy = new DefaultConnectionReuseStrategy(); } /** * @deprecated (4.3) use {@link ProxyClient#ProxyClient(HttpConnectionFactory, ConnectionConfig, RequestConfig)} */ @Deprecated public ProxyClient(final HttpParams params) { this(null, HttpParamConfig.getConnectionConfig(params), HttpClientParamConfig.getRequestConfig(params)); } /** * @since 4.3 */ public ProxyClient(final RequestConfig requestConfig) { this(null, null, requestConfig); } public ProxyClient() { this(null, null, null); } /** * @deprecated (4.3) do not use. */ @Deprecated public HttpParams getParams() { return new BasicHttpParams(); } /** * @deprecated (4.3) do not use. */ @Deprecated public AuthSchemeRegistry getAuthSchemeRegistry() { return this.authSchemeRegistry; } public Socket tunnel( final HttpHost proxy, final HttpHost target, final Credentials credentials) throws IOException, HttpException { Args.notNull(proxy, "Proxy host"); Args.notNull(target, "Target host"); Args.notNull(credentials, "Credentials"); HttpHost host = target; if (host.getPort() <= 0) { host = new HttpHost(host.getHostName(), 80, host.getSchemeName()); } final HttpRoute route = new HttpRoute( host, this.requestConfig.getLocalAddress(), proxy, false, TunnelType.TUNNELLED, LayerType.PLAIN); final ManagedHttpClientConnection conn = this.connFactory.create( route, this.connectionConfig); final HttpContext context = new BasicHttpContext(); HttpResponse response; final HttpRequest connect = new BasicHttpRequest( "CONNECT", host.toHostString(), HttpVersion.HTTP_1_1); final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(new AuthScope(proxy), credentials); // Populate the execution context context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, target); context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); context.setAttribute(HttpCoreContext.HTTP_REQUEST, connect); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.PROXY_AUTH_STATE, this.proxyAuthState); context.setAttribute(HttpClientContext.CREDS_PROVIDER, credsProvider); context.setAttribute(HttpClientContext.AUTHSCHEME_REGISTRY, this.authSchemeRegistry); context.setAttribute(HttpClientContext.REQUEST_CONFIG, this.requestConfig); this.requestExec.preProcess(connect, this.httpProcessor, context); for (;;) { if (!conn.isOpen()) { final Socket socket = new Socket(proxy.getHostName(), proxy.getPort()); conn.bind(socket); } this.authenticator.generateAuthResponse(connect, this.proxyAuthState, context); response = this.requestExec.execute(connect, conn, context); final int status = response.getStatusLine().getStatusCode(); if (status < 200) { throw new HttpException("Unexpected response to CONNECT request: " + response.getStatusLine()); } if (this.authenticator.isAuthenticationRequested(proxy, response, this.proxyAuthStrategy, this.proxyAuthState, context)) { if (this.authenticator.handleAuthChallenge(proxy, response, this.proxyAuthStrategy, this.proxyAuthState, context)) { // Retry request if (this.reuseStrategy.keepAlive(response, context)) { // Consume response content final HttpEntity entity = response.getEntity(); EntityUtils.consume(entity); } else { conn.close(); } // discard previous auth header connect.removeHeaders(AUTH.PROXY_AUTH_RESP); } else { break; } } else { break; } } final int status = response.getStatusLine().getStatusCode(); if (status > 299) { // Buffer response content final HttpEntity entity = response.getEntity(); if (entity != null) { response.setEntity(new BufferedHttpEntity(entity)); } conn.close(); throw new TunnelRefusedException("CONNECT refused by proxy: " + response.getStatusLine(), response); } return conn.getSocket(); } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/RedirectLocations.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/RedirectLocations.j0100644 0000000 0000000 00000016513 12301751710 032424 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.net.URI; import java.util.AbstractList; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.http.annotation.NotThreadSafe; /** * This class represents a collection of {@link java.net.URI}s used * as redirect locations. * * @since 4.0 */ @NotThreadSafe // HashSet/ArrayList are not synch. public class RedirectLocations extends AbstractList { private final Set unique; private final List all; public RedirectLocations() { super(); this.unique = new HashSet(); this.all = new ArrayList(); } /** * Test if the URI is present in the collection. */ public boolean contains(final URI uri) { return this.unique.contains(uri); } /** * Adds a new URI to the collection. */ public void add(final URI uri) { this.unique.add(uri); this.all.add(uri); } /** * Removes a URI from the collection. */ public boolean remove(final URI uri) { final boolean removed = this.unique.remove(uri); if (removed) { final Iterator it = this.all.iterator(); while (it.hasNext()) { final URI current = it.next(); if (current.equals(uri)) { it.remove(); } } } return removed; } /** * Returns all redirect {@link URI}s in the order they were added to the collection. * * @return list of all URIs * * @since 4.1 */ public List getAll() { return new ArrayList(this.all); } /** * Returns the URI at the specified position in this list. * * @param index * index of the location to return * @return the URI at the specified position in this list * @throws IndexOutOfBoundsException * if the index is out of range ( * index < 0 || index >= size()) * @since 4.3 */ @Override public URI get(final int index) { return this.all.get(index); } /** * Returns the number of elements in this list. If this list contains more * than Integer.MAX_VALUE elements, returns * Integer.MAX_VALUE. * * @return the number of elements in this list * @since 4.3 */ @Override public int size() { return this.all.size(); } /** * Replaces the URI at the specified position in this list with the * specified element (must be a URI). * * @param index * index of the element to replace * @param element * URI to be stored at the specified position * @return the URI previously at the specified position * @throws UnsupportedOperationException * if the set operation is not supported by this list * @throws ClassCastException * if the element is not a {@link URI} * @throws NullPointerException * if the specified element is null and this list does not * permit null elements * @throws IndexOutOfBoundsException * if the index is out of range ( * index < 0 || index >= size()) * @since 4.3 */ @Override public Object set(final int index, final Object element) { final URI removed = this.all.set(index, (URI) element); this.unique.remove(removed); this.unique.add((URI) element); if (this.all.size() != this.unique.size()) { this.unique.addAll(this.all); } return removed; } /** * Inserts the specified element at the specified position in this list * (must be a URI). Shifts the URI currently at that position (if any) and * any subsequent URIs to the right (adds one to their indices). * * @param index * index at which the specified element is to be inserted * @param element * URI to be inserted * @throws UnsupportedOperationException * if the add operation is not supported by this list * @throws ClassCastException * if the element is not a {@link URI} * @throws NullPointerException * if the specified element is null and this list does not * permit null elements * @throws IndexOutOfBoundsException * if the index is out of range ( * index < 0 || index > size()) * @since 4.3 */ @Override public void add(final int index, final Object element) { this.all.add(index, (URI) element); this.unique.add((URI) element); } /** * Removes the URI at the specified position in this list. Shifts any * subsequent URIs to the left (subtracts one from their indices). Returns * the URI that was removed from the list. * * @param index * the index of the URI to be removed * @return the URI previously at the specified position * @throws IndexOutOfBoundsException * if the index is out of range ( * index < 0 || index >= size()) * @since 4.3 */ @Override public URI remove(final int index) { final URI removed = this.all.remove(index); this.unique.remove(removed); if (this.all.size() != this.unique.size()) { this.unique.addAll(this.all); } return removed; } /** * Returns true if this collection contains the specified element. * More formally, returns true if and only if this collection * contains at least one element e such that * (o==null ? e==null : o.equals(e)). * * @param o element whose presence in this collection is to be tested * @return true if this collection contains the specified * element */ @Override public boolean contains(final Object o) { return this.unique.contains(o); } } ././@LongLink0100644 0000000 0000000 00000000145 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/RequestWrapper.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/RequestWrapper.java0100644 0000000 0000000 00000011627 12301751711 032472 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.net.URI; import java.net.URISyntaxException; import org.apache.http.HttpRequest; import org.apache.http.ProtocolException; import org.apache.http.ProtocolVersion; import org.apache.http.RequestLine; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.message.AbstractHttpMessage; import org.apache.http.message.BasicRequestLine; import org.apache.http.params.HttpProtocolParams; import org.apache.http.util.Args; /** * A wrapper class for {@link HttpRequest}s that can be used to change * properties of the current request without modifying the original * object. *

* This class is also capable of resetting the request headers to * the state of the original request. * * @since 4.0 * * @deprecated (4.3) do not use. */ @NotThreadSafe @Deprecated public class RequestWrapper extends AbstractHttpMessage implements HttpUriRequest { private final HttpRequest original; private URI uri; private String method; private ProtocolVersion version; private int execCount; public RequestWrapper(final HttpRequest request) throws ProtocolException { super(); Args.notNull(request, "HTTP request"); this.original = request; setParams(request.getParams()); setHeaders(request.getAllHeaders()); // Make a copy of the original URI if (request instanceof HttpUriRequest) { this.uri = ((HttpUriRequest) request).getURI(); this.method = ((HttpUriRequest) request).getMethod(); this.version = null; } else { final RequestLine requestLine = request.getRequestLine(); try { this.uri = new URI(requestLine.getUri()); } catch (final URISyntaxException ex) { throw new ProtocolException("Invalid request URI: " + requestLine.getUri(), ex); } this.method = requestLine.getMethod(); this.version = request.getProtocolVersion(); } this.execCount = 0; } public void resetHeaders() { // Make a copy of original headers this.headergroup.clear(); setHeaders(this.original.getAllHeaders()); } public String getMethod() { return this.method; } public void setMethod(final String method) { Args.notNull(method, "Method name"); this.method = method; } public ProtocolVersion getProtocolVersion() { if (this.version == null) { this.version = HttpProtocolParams.getVersion(getParams()); } return this.version; } public void setProtocolVersion(final ProtocolVersion version) { this.version = version; } public URI getURI() { return this.uri; } public void setURI(final URI uri) { this.uri = uri; } public RequestLine getRequestLine() { final String method = getMethod(); final ProtocolVersion ver = getProtocolVersion(); String uritext = null; if (uri != null) { uritext = uri.toASCIIString(); } if (uritext == null || uritext.length() == 0) { uritext = "/"; } return new BasicRequestLine(method, uritext, ver); } public void abort() throws UnsupportedOperationException { throw new UnsupportedOperationException(); } public boolean isAborted() { return false; } public HttpRequest getOriginal() { return this.original; } public boolean isRepeatable() { return true; } public int getExecCount() { return this.execCount; } public void incrementExecCount() { this.execCount++; } } ././@LongLink0100644 0000000 0000000 00000000166 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/StandardHttpRequestRetryHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/StandardHttpRequest0100644 0000000 0000000 00000005616 12301751711 032533 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.http.HttpRequest; import org.apache.http.annotation.Immutable; /** * {@link org.apache.http.client.HttpRequestRetryHandler} which assumes * that all requested HTTP methods which should be idempotent according * to RFC-2616 are in fact idempotent and can be retried. *

* According to RFC-2616 section 9.1.2 the idempotent HTTP methods are: * GET, HEAD, PUT, DELETE, OPTIONS, and TRACE * * @since 4.2 */ @Immutable public class StandardHttpRequestRetryHandler extends DefaultHttpRequestRetryHandler { private final Map idempotentMethods; /** * Default constructor */ public StandardHttpRequestRetryHandler(final int retryCount, final boolean requestSentRetryEnabled) { super(retryCount, requestSentRetryEnabled); this.idempotentMethods = new ConcurrentHashMap(); this.idempotentMethods.put("GET", Boolean.TRUE); this.idempotentMethods.put("HEAD", Boolean.TRUE); this.idempotentMethods.put("PUT", Boolean.TRUE); this.idempotentMethods.put("DELETE", Boolean.TRUE); this.idempotentMethods.put("OPTIONS", Boolean.TRUE); this.idempotentMethods.put("TRACE", Boolean.TRUE); } /** * Default constructor */ public StandardHttpRequestRetryHandler() { this(3, false); } @Override protected boolean handleAsIdempotent(final HttpRequest request) { final String method = request.getRequestLine().getMethod().toUpperCase(Locale.US); final Boolean b = this.idempotentMethods.get(method); return b != null && b.booleanValue(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/SystemClock.java0100644 0000000 0000000 00000002570 12301751711 031736 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; /** * The actual system clock. * * @since 4.2 */ class SystemClock implements Clock { public long getCurrentTime() { return System.currentTimeMillis(); } } ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/SystemDefaultCredentialsProvider.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/SystemDefaultCreden0100644 0000000 0000000 00000012573 12301751711 032474 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.net.Authenticator; import java.net.PasswordAuthentication; import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.http.annotation.ThreadSafe; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.apache.http.auth.NTCredentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.AuthSchemes; import org.apache.http.util.Args; /** * Implementation of {@link CredentialsProvider} backed by standard * JRE {@link Authenticator}. * * @since 4.3 */ @ThreadSafe public class SystemDefaultCredentialsProvider implements CredentialsProvider { private static final Map SCHEME_MAP; static { SCHEME_MAP = new ConcurrentHashMap(); SCHEME_MAP.put(AuthSchemes.BASIC.toUpperCase(Locale.ENGLISH), "Basic"); SCHEME_MAP.put(AuthSchemes.DIGEST.toUpperCase(Locale.ENGLISH), "Digest"); SCHEME_MAP.put(AuthSchemes.NTLM.toUpperCase(Locale.ENGLISH), "NTLM"); SCHEME_MAP.put(AuthSchemes.SPNEGO.toUpperCase(Locale.ENGLISH), "SPNEGO"); SCHEME_MAP.put(AuthSchemes.KERBEROS.toUpperCase(Locale.ENGLISH), "Kerberos"); } private static String translateScheme(final String key) { if (key == null) { return null; } final String s = SCHEME_MAP.get(key); return s != null ? s : key; } private final BasicCredentialsProvider internal; /** * Default constructor. */ public SystemDefaultCredentialsProvider() { super(); this.internal = new BasicCredentialsProvider(); } public void setCredentials(final AuthScope authscope, final Credentials credentials) { internal.setCredentials(authscope, credentials); } private static PasswordAuthentication getSystemCreds( final AuthScope authscope, final Authenticator.RequestorType requestorType) { final String hostname = authscope.getHost(); final int port = authscope.getPort(); final String protocol = port == 443 ? "https" : "http"; return Authenticator.requestPasswordAuthentication( hostname, null, port, protocol, null, translateScheme(authscope.getScheme()), null, requestorType); } public Credentials getCredentials(final AuthScope authscope) { Args.notNull(authscope, "Auth scope"); final Credentials localcreds = internal.getCredentials(authscope); if (localcreds != null) { return localcreds; } if (authscope.getHost() != null) { PasswordAuthentication systemcreds = getSystemCreds( authscope, Authenticator.RequestorType.SERVER); if (systemcreds == null) { systemcreds = getSystemCreds( authscope, Authenticator.RequestorType.PROXY); } if (systemcreds != null) { final String domain = System.getProperty("http.auth.ntlm.domain"); if (domain != null) { return new NTCredentials( systemcreds.getUserName(), new String(systemcreds.getPassword()), null, domain); } else { if (AuthSchemes.NTLM.equalsIgnoreCase(authscope.getScheme())) { // Domian may be specified in a fully qualified user name return new NTCredentials( systemcreds.getUserName(), new String(systemcreds.getPassword()), null, null); } else { return new UsernamePasswordCredentials( systemcreds.getUserName(), new String(systemcreds.getPassword())); } } } } return null; } public void clear() { internal.clear(); } } ././@LongLink0100644 0000000 0000000 00000000163 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/TargetAuthenticationStrategy.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/client/TargetAuthenticatio0100644 0000000 0000000 00000003737 12301751711 032534 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.Collection; import org.apache.http.HttpStatus; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AUTH; import org.apache.http.client.config.RequestConfig; /** * Default {@link org.apache.http.client.AuthenticationStrategy} implementation * for proxy host authentication. * * @since 4.2 */ @Immutable public class TargetAuthenticationStrategy extends AuthenticationStrategyImpl { public static final TargetAuthenticationStrategy INSTANCE = new TargetAuthenticationStrategy(); public TargetAuthenticationStrategy() { super(HttpStatus.SC_UNAUTHORIZED, AUTH.WWW_AUTH); } @Override Collection getPreferredAuthSchemes(final RequestConfig config) { return config.getTargetPreferredAuthSchemes(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/0040755 0000000 0000000 00000000000 12301751706 026315 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/BasicHttpClientConnectionManager.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/BasicHttpClientConnec0100644 0000000 0000000 00000031423 12301751706 032406 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.Closeable; import java.io.IOException; import java.net.InetSocketAddress; import java.util.Date; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpClientConnection; import org.apache.http.HttpHost; import org.apache.http.annotation.GuardedBy; import org.apache.http.annotation.ThreadSafe; import org.apache.http.config.ConnectionConfig; import org.apache.http.config.Lookup; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.config.SocketConfig; import org.apache.http.conn.ConnectionRequest; import org.apache.http.conn.DnsResolver; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.conn.HttpConnectionFactory; import org.apache.http.conn.SchemePortResolver; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.Asserts; import org.apache.http.util.LangUtils; /** * A connection manager for a single connection. This connection manager maintains only one active * connection. Even though this class is fully thread-safe it ought to be used by one execution * thread only, as only one thread a time can lease the connection at a time. *

* This connection manager will make an effort to reuse the connection for subsequent requests * with the same {@link HttpRoute route}. It will, however, close the existing connection and * open it for the given route, if the route of the persistent connection does not match that * of the connection request. If the connection has been already been allocated * {@link IllegalStateException} is thrown. *

* This connection manager implementation should be used inside an EJB container instead of * {@link PoolingHttpClientConnectionManager}. * * @since 4.3 */ @ThreadSafe public class BasicHttpClientConnectionManager implements HttpClientConnectionManager, Closeable { private final Log log = LogFactory.getLog(getClass()); private final HttpClientConnectionOperator connectionOperator; private final HttpConnectionFactory connFactory; @GuardedBy("this") private ManagedHttpClientConnection conn; @GuardedBy("this") private HttpRoute route; @GuardedBy("this") private Object state; @GuardedBy("this") private long updated; @GuardedBy("this") private long expiry; @GuardedBy("this") private boolean leased; @GuardedBy("this") private SocketConfig socketConfig; @GuardedBy("this") private ConnectionConfig connConfig; @GuardedBy("this") private volatile boolean shutdown; private static Registry getDefaultRegistry() { return RegistryBuilder.create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", SSLConnectionSocketFactory.getSocketFactory()) .build(); } public BasicHttpClientConnectionManager( final Lookup socketFactoryRegistry, final HttpConnectionFactory connFactory, final SchemePortResolver schemePortResolver, final DnsResolver dnsResolver) { super(); this.connectionOperator = new HttpClientConnectionOperator( socketFactoryRegistry, schemePortResolver, dnsResolver); this.connFactory = connFactory != null ? connFactory : ManagedHttpClientConnectionFactory.INSTANCE; this.expiry = Long.MAX_VALUE; this.socketConfig = SocketConfig.DEFAULT; this.connConfig = ConnectionConfig.DEFAULT; } public BasicHttpClientConnectionManager( final Lookup socketFactoryRegistry, final HttpConnectionFactory connFactory) { this(socketFactoryRegistry, connFactory, null, null); } public BasicHttpClientConnectionManager( final Lookup socketFactoryRegistry) { this(socketFactoryRegistry, null, null, null); } public BasicHttpClientConnectionManager() { this(getDefaultRegistry(), null, null, null); } @Override protected void finalize() throws Throwable { try { shutdown(); } finally { // Make sure we call overridden method even if shutdown barfs super.finalize(); } } public void close() { shutdown(); } HttpRoute getRoute() { return route; } Object getState() { return state; } public synchronized SocketConfig getSocketConfig() { return socketConfig; } public synchronized void setSocketConfig(final SocketConfig socketConfig) { this.socketConfig = socketConfig != null ? socketConfig : SocketConfig.DEFAULT; } public synchronized ConnectionConfig getConnectionConfig() { return connConfig; } public synchronized void setConnectionConfig(final ConnectionConfig connConfig) { this.connConfig = connConfig != null ? connConfig : ConnectionConfig.DEFAULT; } public final ConnectionRequest requestConnection( final HttpRoute route, final Object state) { Args.notNull(route, "Route"); return new ConnectionRequest() { public boolean cancel() { // Nothing to abort, since requests are immediate. return false; } public HttpClientConnection get(final long timeout, final TimeUnit tunit) { return BasicHttpClientConnectionManager.this.getConnection( route, state); } }; } private void closeConnection() { if (this.conn != null) { this.log.debug("Closing connection"); try { this.conn.close(); } catch (final IOException iox) { if (this.log.isDebugEnabled()) { this.log.debug("I/O exception closing connection", iox); } } this.conn = null; } } private void shutdownConnection() { if (this.conn != null) { this.log.debug("Shutting down connection"); try { this.conn.shutdown(); } catch (final IOException iox) { if (this.log.isDebugEnabled()) { this.log.debug("I/O exception shutting down connection", iox); } } this.conn = null; } } private void checkExpiry() { if (this.conn != null && System.currentTimeMillis() >= this.expiry) { if (this.log.isDebugEnabled()) { this.log.debug("Connection expired @ " + new Date(this.expiry)); } closeConnection(); } } synchronized HttpClientConnection getConnection(final HttpRoute route, final Object state) { Asserts.check(!this.shutdown, "Connection manager has been shut down"); if (this.log.isDebugEnabled()) { this.log.debug("Get connection for route " + route); } Asserts.check(!this.leased, "Connection is still allocated"); if (!LangUtils.equals(this.route, route) || !LangUtils.equals(this.state, state)) { closeConnection(); } this.route = route; this.state = state; checkExpiry(); if (this.conn == null) { this.conn = this.connFactory.create(route, this.connConfig); } this.leased = true; return this.conn; } public synchronized void releaseConnection( final HttpClientConnection conn, final Object state, final long keepalive, final TimeUnit tunit) { Args.notNull(conn, "Connection"); Asserts.check(conn == this.conn, "Connection not obtained from this manager"); if (this.log.isDebugEnabled()) { this.log.debug("Releasing connection " + conn); } if (this.shutdown) { shutdownConnection(); return; } try { this.updated = System.currentTimeMillis(); if (!this.conn.isOpen()) { this.conn = null; this.route = null; this.conn = null; this.expiry = Long.MAX_VALUE; } else { this.state = state; if (this.log.isDebugEnabled()) { final String s; if (keepalive > 0) { s = "for " + keepalive + " " + tunit; } else { s = "indefinitely"; } this.log.debug("Connection can be kept alive " + s); } if (keepalive > 0) { this.expiry = this.updated + tunit.toMillis(keepalive); } else { this.expiry = Long.MAX_VALUE; } } } finally { this.leased = false; } } public void connect( final HttpClientConnection conn, final HttpRoute route, final int connectTimeout, final HttpContext context) throws IOException { Args.notNull(conn, "Connection"); Args.notNull(route, "HTTP route"); Asserts.check(conn == this.conn, "Connection not obtained from this manager"); final HttpHost host; if (route.getProxyHost() != null) { host = route.getProxyHost(); } else { host = route.getTargetHost(); } final InetSocketAddress localAddress = route.getLocalSocketAddress(); this.connectionOperator.connect(this.conn, host, localAddress, connectTimeout, this.socketConfig, context); } public void upgrade( final HttpClientConnection conn, final HttpRoute route, final HttpContext context) throws IOException { Args.notNull(conn, "Connection"); Args.notNull(route, "HTTP route"); Asserts.check(conn == this.conn, "Connection not obtained from this manager"); this.connectionOperator.upgrade(this.conn, route.getTargetHost(), context); } public void routeComplete( final HttpClientConnection conn, final HttpRoute route, final HttpContext context) throws IOException { } public synchronized void closeExpiredConnections() { if (this.shutdown) { return; } if (!this.leased) { checkExpiry(); } } public synchronized void closeIdleConnections(final long idletime, final TimeUnit tunit) { Args.notNull(tunit, "Time unit"); if (this.shutdown) { return; } if (!this.leased) { long time = tunit.toMillis(idletime); if (time < 0) { time = 0; } final long deadline = System.currentTimeMillis() - time; if (this.updated <= deadline) { closeConnection(); } } } public synchronized void shutdown() { if (this.shutdown) { return; } this.shutdown = true; shutdownConnection(); } } ././@LongLink0100644 0000000 0000000 00000000160 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/ConnectionShutdownException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/ConnectionShutdownExc0100644 0000000 0000000 00000003265 12301751706 032536 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import org.apache.http.annotation.Immutable; /** * Signals that the connection has been shut down or released back to the * the connection pool * * @since 4.1 */ @Immutable public class ConnectionShutdownException extends IllegalStateException { private static final long serialVersionUID = 5868657401162844497L; /** * Creates a new ConnectionShutdownException with a null detail message. */ public ConnectionShutdownException() { super(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/CPool.java0100644 0000000 0000000 00000005027 12301751706 030175 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.annotation.ThreadSafe; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.pool.AbstractConnPool; import org.apache.http.pool.ConnFactory; /** * @since 4.3 */ @ThreadSafe class CPool extends AbstractConnPool { private static final AtomicLong COUNTER = new AtomicLong(); private final Log log = LogFactory.getLog(CPool.class); private final long timeToLive; private final TimeUnit tunit; public CPool( final ConnFactory connFactory, final int defaultMaxPerRoute, final int maxTotal, final long timeToLive, final TimeUnit tunit) { super(connFactory, defaultMaxPerRoute, maxTotal); this.timeToLive = timeToLive; this.tunit = tunit; } @Override protected CPoolEntry createEntry(final HttpRoute route, final ManagedHttpClientConnection conn) { final String id = Long.toString(COUNTER.getAndIncrement()); return new CPoolEntry(this.log, id, route, conn, this.timeToLive, this.tunit); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/CPoolEntry.java0100644 0000000 0000000 00000006152 12301751706 031217 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.util.Date; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.http.HttpClientConnection; import org.apache.http.annotation.ThreadSafe; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.pool.PoolEntry; /** * @since 4.3 */ @ThreadSafe class CPoolEntry extends PoolEntry { private final Log log; private volatile boolean routeComplete; public CPoolEntry( final Log log, final String id, final HttpRoute route, final ManagedHttpClientConnection conn, final long timeToLive, final TimeUnit tunit) { super(id, route, conn, timeToLive, tunit); this.log = log; } public void markRouteComplete() { this.routeComplete = true; } public boolean isRouteComplete() { return this.routeComplete; } public void closeConnection() throws IOException { final HttpClientConnection conn = getConnection(); conn.close(); } public void shutdownConnection() throws IOException { final HttpClientConnection conn = getConnection(); conn.shutdown(); } @Override public boolean isExpired(final long now) { final boolean expired = super.isExpired(now); if (expired && this.log.isDebugEnabled()) { this.log.debug("Connection " + this + " expired @ " + new Date(getExpiry())); } return expired; } @Override public boolean isClosed() { final HttpClientConnection conn = getConnection(); return !conn.isOpen(); } @Override public void close() { try { closeConnection(); } catch (final IOException ex) { this.log.debug("I/O error closing connection", ex); } } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/CPoolProxy.java0100644 0000000 0000000 00000013274 12301751706 031242 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import org.apache.http.HttpClientConnection; import org.apache.http.HttpConnection; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.protocol.HttpContext; /** * @since 4.3 */ @NotThreadSafe class CPoolProxy implements InvocationHandler { private static final Method CLOSE_METHOD; private static final Method SHUTDOWN_METHOD; private static final Method IS_OPEN_METHOD; private static final Method IS_STALE_METHOD; static { try { CLOSE_METHOD = HttpConnection.class.getMethod("close"); SHUTDOWN_METHOD = HttpConnection.class.getMethod("shutdown"); IS_OPEN_METHOD = HttpConnection.class.getMethod("isOpen"); IS_STALE_METHOD = HttpConnection.class.getMethod("isStale"); } catch (final NoSuchMethodException ex) { throw new Error(ex); } } private volatile CPoolEntry poolEntry; CPoolProxy(final CPoolEntry entry) { super(); this.poolEntry = entry; } CPoolEntry getPoolEntry() { return this.poolEntry; } CPoolEntry detach() { final CPoolEntry local = this.poolEntry; this.poolEntry = null; return local; } HttpClientConnection getConnection() { final CPoolEntry local = this.poolEntry; if (local == null) { return null; } return local.getConnection(); } public void close() throws IOException { final CPoolEntry local = this.poolEntry; if (local != null) { local.closeConnection(); } } public void shutdown() throws IOException { final CPoolEntry local = this.poolEntry; if (local != null) { local.shutdownConnection(); } } public boolean isOpen() { final CPoolEntry local = this.poolEntry; if (local != null) { return !local.isClosed(); } else { return false; } } public boolean isStale() { final HttpClientConnection conn = getConnection(); if (conn != null) { return conn.isStale(); } else { return true; } } public Object invoke( final Object proxy, final Method method, final Object[] args) throws Throwable { if (method.equals(CLOSE_METHOD)) { close(); return null; } else if (method.equals(SHUTDOWN_METHOD)) { shutdown(); return null; } else if (method.equals(IS_OPEN_METHOD)) { return Boolean.valueOf(isOpen()); } else if (method.equals(IS_STALE_METHOD)) { return Boolean.valueOf(isStale()); } else { final HttpClientConnection conn = getConnection(); if (conn == null) { throw new ConnectionShutdownException(); } try { return method.invoke(conn, args); } catch (final InvocationTargetException ex) { final Throwable cause = ex.getCause(); if (cause != null) { throw cause; } else { throw ex; } } } } public static HttpClientConnection newProxy( final CPoolEntry poolEntry) { return (HttpClientConnection) Proxy.newProxyInstance( CPoolProxy.class.getClassLoader(), new Class[] { ManagedHttpClientConnection.class, HttpContext.class }, new CPoolProxy(poolEntry)); } private static CPoolProxy getHandler( final HttpClientConnection proxy) { final InvocationHandler handler = Proxy.getInvocationHandler(proxy); if (!CPoolProxy.class.isInstance(handler)) { throw new IllegalStateException("Unexpected proxy handler class: " + handler); } return CPoolProxy.class.cast(handler); } public static CPoolEntry getPoolEntry(final HttpClientConnection proxy) { final CPoolEntry entry = getHandler(proxy).getPoolEntry(); if (entry == null) { throw new ConnectionShutdownException(); } return entry; } public static CPoolEntry detach(final HttpClientConnection proxy) { return getHandler(proxy).detach(); } } ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/DefaultHttpResponseParser.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/DefaultHttpResponsePa0100644 0000000 0000000 00000014435 12301751706 032470 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpException; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseFactory; import org.apache.http.NoHttpResponseException; import org.apache.http.ProtocolException; import org.apache.http.StatusLine; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.config.MessageConstraints; import org.apache.http.impl.DefaultHttpResponseFactory; import org.apache.http.impl.io.AbstractMessageParser; import org.apache.http.io.SessionInputBuffer; import org.apache.http.message.LineParser; import org.apache.http.message.ParserCursor; import org.apache.http.params.HttpParams; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; /** * Lenient HTTP response parser implementation that can skip malformed data until * a valid HTTP response message head is encountered. * * @since 4.2 */ @SuppressWarnings("deprecation") @NotThreadSafe public class DefaultHttpResponseParser extends AbstractMessageParser { private final Log log = LogFactory.getLog(getClass()); private final HttpResponseFactory responseFactory; private final CharArrayBuffer lineBuf; /** * @deprecated (4.3) use {@link DefaultHttpResponseParser#DefaultHttpResponseParser( * SessionInputBuffer, LineParser, HttpResponseFactory, MessageConstraints)} */ @Deprecated public DefaultHttpResponseParser( final SessionInputBuffer buffer, final LineParser parser, final HttpResponseFactory responseFactory, final HttpParams params) { super(buffer, parser, params); Args.notNull(responseFactory, "Response factory"); this.responseFactory = responseFactory; this.lineBuf = new CharArrayBuffer(128); } /** * Creates new instance of DefaultHttpResponseParser. * * @param buffer the session input buffer. * @param lineParser the line parser. If null * {@link org.apache.http.message.BasicLineParser#INSTANCE} will be used. * @param responseFactory HTTP response factory. If null * {@link DefaultHttpResponseFactory#INSTANCE} will be used. * @param constraints the message constraints. If null * {@link MessageConstraints#DEFAULT} will be used. * * @since 4.3 */ public DefaultHttpResponseParser( final SessionInputBuffer buffer, final LineParser lineParser, final HttpResponseFactory responseFactory, final MessageConstraints constraints) { super(buffer, lineParser, constraints); this.responseFactory = responseFactory != null ? responseFactory : DefaultHttpResponseFactory.INSTANCE; this.lineBuf = new CharArrayBuffer(128); } /** * Creates new instance of DefaultHttpResponseParser. * * @param buffer the session input buffer. * @param constraints the message constraints. If null * {@link MessageConstraints#DEFAULT} will be used. * * @since 4.3 */ public DefaultHttpResponseParser( final SessionInputBuffer buffer, final MessageConstraints constraints) { this(buffer, null, null, constraints); } /** * Creates new instance of DefaultHttpResponseParser. * * @param buffer the session input buffer. * * @since 4.3 */ public DefaultHttpResponseParser(final SessionInputBuffer buffer) { this(buffer, null, null, MessageConstraints.DEFAULT); } @Override protected HttpResponse parseHead( final SessionInputBuffer sessionBuffer) throws IOException, HttpException { //read out the HTTP status string int count = 0; ParserCursor cursor = null; do { // clear the buffer this.lineBuf.clear(); final int i = sessionBuffer.readLine(this.lineBuf); if (i == -1 && count == 0) { // The server just dropped connection on us throw new NoHttpResponseException("The target server failed to respond"); } cursor = new ParserCursor(0, this.lineBuf.length()); if (lineParser.hasProtocolVersion(this.lineBuf, cursor)) { // Got one break; } else if (i == -1 || reject(this.lineBuf, count)) { // Giving up throw new ProtocolException("The server failed to respond with a " + "valid HTTP response"); } if (this.log.isDebugEnabled()) { this.log.debug("Garbage in response: " + this.lineBuf.toString()); } count++; } while(true); //create the status line from the status string final StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor); return this.responseFactory.newHttpResponse(statusline, null); } protected boolean reject(final CharArrayBuffer line, final int count) { return false; } } ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/DefaultHttpResponseParserFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/DefaultHttpResponsePa0100644 0000000 0000000 00000005556 12301751706 032474 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseFactory; import org.apache.http.annotation.Immutable; import org.apache.http.config.MessageConstraints; import org.apache.http.impl.DefaultHttpResponseFactory; import org.apache.http.io.HttpMessageParser; import org.apache.http.io.HttpMessageParserFactory; import org.apache.http.io.SessionInputBuffer; import org.apache.http.message.BasicLineParser; import org.apache.http.message.LineParser; /** * Default factory for response message parsers. * * @since 4.3 */ @Immutable public class DefaultHttpResponseParserFactory implements HttpMessageParserFactory { public static final DefaultHttpResponseParserFactory INSTANCE = new DefaultHttpResponseParserFactory(); private final LineParser lineParser; private final HttpResponseFactory responseFactory; public DefaultHttpResponseParserFactory( final LineParser lineParser, final HttpResponseFactory responseFactory) { super(); this.lineParser = lineParser != null ? lineParser : BasicLineParser.INSTANCE; this.responseFactory = responseFactory != null ? responseFactory : DefaultHttpResponseFactory.INSTANCE; } public DefaultHttpResponseParserFactory( final HttpResponseFactory responseFactory) { this(null, responseFactory); } public DefaultHttpResponseParserFactory() { this(null, null); } public HttpMessageParser create(final SessionInputBuffer buffer, final MessageConstraints constraints) { return new DefaultHttpResponseParser(buffer, lineParser, responseFactory, constraints); } } ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/DefaultManagedHttpClientConnection.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/DefaultManagedHttpCli0100644 0000000 0000000 00000011113 12301751706 032363 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.io.InterruptedIOException; import java.net.Socket; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.config.MessageConstraints; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.entity.ContentLengthStrategy; import org.apache.http.impl.DefaultBHttpClientConnection; import org.apache.http.io.HttpMessageParserFactory; import org.apache.http.io.HttpMessageWriterFactory; import org.apache.http.protocol.HttpContext; /** * Default {@link ManagedHttpClientConnection} implementation. * @since 4.3 */ @NotThreadSafe public class DefaultManagedHttpClientConnection extends DefaultBHttpClientConnection implements ManagedHttpClientConnection, HttpContext { private final String id; private final Map attributes; private volatile boolean shutdown; public DefaultManagedHttpClientConnection( final String id, final int buffersize, final int fragmentSizeHint, final CharsetDecoder chardecoder, final CharsetEncoder charencoder, final MessageConstraints constraints, final ContentLengthStrategy incomingContentStrategy, final ContentLengthStrategy outgoingContentStrategy, final HttpMessageWriterFactory requestWriterFactory, final HttpMessageParserFactory responseParserFactory) { super(buffersize, fragmentSizeHint, chardecoder, charencoder, constraints, incomingContentStrategy, outgoingContentStrategy, requestWriterFactory, responseParserFactory); this.id = id; this.attributes = new ConcurrentHashMap(); } public DefaultManagedHttpClientConnection( final String id, final int buffersize) { this(id, buffersize, buffersize, null, null, null, null, null, null, null); } public String getId() { return this.id; } @Override public void shutdown() throws IOException { this.shutdown = true; super.shutdown(); } public Object getAttribute(final String id) { return this.attributes.get(id); } public Object removeAttribute(final String id) { return this.attributes.remove(id); } public void setAttribute(final String id, final Object obj) { this.attributes.put(id, obj); } @Override public void bind(final Socket socket) throws IOException { if (this.shutdown) { socket.close(); // allow this to throw... // ...but if it doesn't, explicitly throw one ourselves. throw new InterruptedIOException("Connection already shutdown"); } super.bind(socket); } @Override public Socket getSocket() { return super.getSocket(); } public SSLSession getSSLSession() { final Socket socket = super.getSocket(); if (socket instanceof SSLSocket) { return ((SSLSocket) socket).getSession(); } else { return null; } } } ././@LongLink0100644 0000000 0000000 00000000155 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/DefaultProxyRoutePlanner.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/DefaultProxyRoutePlan0100644 0000000 0000000 00000004341 12301751706 032517 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.annotation.Immutable; import org.apache.http.conn.SchemePortResolver; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Implementation of an {@link org.apache.http.conn.routing.HttpRoutePlanner} * that routes requests through a default proxy. * * @since 4.3 */ @Immutable public class DefaultProxyRoutePlanner extends DefaultRoutePlanner { private final HttpHost proxy; public DefaultProxyRoutePlanner(final HttpHost proxy, final SchemePortResolver schemePortResolver) { super(schemePortResolver); this.proxy = Args.notNull(proxy, "Proxy host"); } public DefaultProxyRoutePlanner(final HttpHost proxy) { this(proxy, null); } @Override protected HttpHost determineProxy( final HttpHost target, final HttpRequest request, final HttpContext context) throws HttpException { return proxy; } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/DefaultRoutePlanner.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/DefaultRoutePlanner.j0100644 0000000 0000000 00000007462 12301751706 032421 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.net.InetAddress; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.annotation.Immutable; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.SchemePortResolver; import org.apache.http.conn.UnsupportedSchemeException; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Default implementation of an {@link HttpRoutePlanner}. It will not make use of * any Java system properties, nor of system or browser proxy settings. * * @since 4.3 */ @Immutable public class DefaultRoutePlanner implements HttpRoutePlanner { private final SchemePortResolver schemePortResolver; public DefaultRoutePlanner(final SchemePortResolver schemePortResolver) { super(); this.schemePortResolver = schemePortResolver != null ? schemePortResolver : DefaultSchemePortResolver.INSTANCE; } public HttpRoute determineRoute( final HttpHost host, final HttpRequest request, final HttpContext context) throws HttpException { Args.notNull(host, "Target host"); Args.notNull(request, "Request"); final HttpClientContext clientContext = HttpClientContext.adapt(context); final RequestConfig config = clientContext.getRequestConfig(); final InetAddress local = config.getLocalAddress(); HttpHost proxy = config.getProxy(); if (proxy == null) { proxy = determineProxy(host, request, context); } final HttpHost target; if (host.getPort() <= 0) { try { target = new HttpHost( host.getHostName(), this.schemePortResolver.resolve(host), host.getSchemeName()); } catch (final UnsupportedSchemeException ex) { throw new HttpException(ex.getMessage()); } } else { target = host; } final boolean secure = target.getSchemeName().equalsIgnoreCase("https"); if (proxy == null) { return new HttpRoute(target, local, secure); } else { return new HttpRoute(target, local, proxy, secure); } } protected HttpHost determineProxy( final HttpHost target, final HttpRequest request, final HttpContext context) throws HttpException { return null; } } ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/DefaultSchemePortResolver.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/DefaultSchemePortReso0100644 0000000 0000000 00000004252 12301751706 032447 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import org.apache.http.HttpHost; import org.apache.http.annotation.Immutable; import org.apache.http.conn.SchemePortResolver; import org.apache.http.conn.UnsupportedSchemeException; import org.apache.http.util.Args; /** * Default {@link SchemePortResolver}. * * @since 4.3 */ @Immutable public class DefaultSchemePortResolver implements SchemePortResolver { public static final DefaultSchemePortResolver INSTANCE = new DefaultSchemePortResolver(); public int resolve(final HttpHost host) throws UnsupportedSchemeException { Args.notNull(host, "HTTP host"); final int port = host.getPort(); if (port > 0) { return port; } final String name = host.getSchemeName(); if (name.equalsIgnoreCase("http")) { return 80; } else if (name.equalsIgnoreCase("https")) { return 443; } else { throw new UnsupportedSchemeException(name + " protocol is not supported"); } } } ././@LongLink0100644 0000000 0000000 00000000161 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/HttpClientConnectionOperator.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/HttpClientConnectionO0100644 0000000 0000000 00000016643 12301751706 032464 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.net.ConnectException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketTimeoutException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpHost; import org.apache.http.annotation.Immutable; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.Lookup; import org.apache.http.config.SocketConfig; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.DnsResolver; import org.apache.http.conn.HttpHostConnectException; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.conn.SchemePortResolver; import org.apache.http.conn.UnsupportedSchemeException; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.LayeredConnectionSocketFactory; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; @Immutable class HttpClientConnectionOperator { static final String SOCKET_FACTORY_REGISTRY = "http.socket-factory-registry"; private final Log log = LogFactory.getLog(getClass()); private final Lookup socketFactoryRegistry; private final SchemePortResolver schemePortResolver; private final DnsResolver dnsResolver; HttpClientConnectionOperator( final Lookup socketFactoryRegistry, final SchemePortResolver schemePortResolver, final DnsResolver dnsResolver) { super(); Args.notNull(socketFactoryRegistry, "Socket factory registry"); this.socketFactoryRegistry = socketFactoryRegistry; this.schemePortResolver = schemePortResolver != null ? schemePortResolver : DefaultSchemePortResolver.INSTANCE; this.dnsResolver = dnsResolver != null ? dnsResolver : SystemDefaultDnsResolver.INSTANCE; } @SuppressWarnings("unchecked") private Lookup getSocketFactoryRegistry(final HttpContext context) { Lookup reg = (Lookup) context.getAttribute( SOCKET_FACTORY_REGISTRY); if (reg == null) { reg = this.socketFactoryRegistry; } return reg; } public void connect( final ManagedHttpClientConnection conn, final HttpHost host, final InetSocketAddress localAddress, final int connectTimeout, final SocketConfig socketConfig, final HttpContext context) throws IOException { final Lookup registry = getSocketFactoryRegistry(context); final ConnectionSocketFactory sf = registry.lookup(host.getSchemeName()); if (sf == null) { throw new UnsupportedSchemeException(host.getSchemeName() + " protocol is not supported"); } final InetAddress[] addresses = this.dnsResolver.resolve(host.getHostName()); final int port = this.schemePortResolver.resolve(host); for (int i = 0; i < addresses.length; i++) { final InetAddress address = addresses[i]; final boolean last = i == addresses.length - 1; Socket sock = sf.createSocket(context); sock.setReuseAddress(socketConfig.isSoReuseAddress()); conn.bind(sock); final InetSocketAddress remoteAddress = new InetSocketAddress(address, port); if (this.log.isDebugEnabled()) { this.log.debug("Connecting to " + remoteAddress); } try { sock.setSoTimeout(socketConfig.getSoTimeout()); sock = sf.connectSocket( connectTimeout, sock, host, remoteAddress, localAddress, context); sock.setTcpNoDelay(socketConfig.isTcpNoDelay()); sock.setKeepAlive(socketConfig.isSoKeepAlive()); final int linger = socketConfig.getSoLinger(); if (linger >= 0) { sock.setSoLinger(linger > 0, linger); } conn.bind(sock); if (this.log.isDebugEnabled()) { this.log.debug("Connection established " + conn); } return; } catch (final SocketTimeoutException ex) { if (last) { throw new ConnectTimeoutException(ex, host, addresses); } } catch (final ConnectException ex) { if (last) { final String msg = ex.getMessage(); if ("Connection timed out".equals(msg)) { throw new ConnectTimeoutException(ex, host, addresses); } else { throw new HttpHostConnectException(ex, host, addresses); } } } if (this.log.isDebugEnabled()) { this.log.debug("Connect to " + remoteAddress + " timed out. " + "Connection will be retried using another IP address"); } } } public void upgrade( final ManagedHttpClientConnection conn, final HttpHost host, final HttpContext context) throws IOException { final HttpClientContext clientContext = HttpClientContext.adapt(context); final Lookup registry = getSocketFactoryRegistry(clientContext); final ConnectionSocketFactory sf = registry.lookup(host.getSchemeName()); if (sf == null) { throw new UnsupportedSchemeException(host.getSchemeName() + " protocol is not supported"); } if (!(sf instanceof LayeredConnectionSocketFactory)) { throw new UnsupportedSchemeException(host.getSchemeName() + " protocol does not support connection upgrade"); } final LayeredConnectionSocketFactory lsf = (LayeredConnectionSocketFactory) sf; Socket sock = conn.getSocket(); final int port = this.schemePortResolver.resolve(host); sock = lsf.createLayeredSocket(sock, host.getHostName(), port, context); conn.bind(sock); } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/InMemoryDnsResolver.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/InMemoryDnsResolver.j0100644 0000000 0000000 00000006351 12301751706 032420 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.conn.DnsResolver; import org.apache.http.util.Args; /** * In-memory {@link DnsResolver} implementation. * * @since 4.2 */ public class InMemoryDnsResolver implements DnsResolver { /** Logger associated to this class. */ private final Log log = LogFactory.getLog(InMemoryDnsResolver.class); /** * In-memory collection that will hold the associations between a host name * and an array of InetAddress instances. */ private final Map dnsMap; /** * Builds a DNS resolver that will resolve the host names against a * collection held in-memory. */ public InMemoryDnsResolver() { dnsMap = new ConcurrentHashMap(); } /** * Associates the given array of IP addresses to the given host in this DNS overrider. * The IP addresses are assumed to be already resolved. * * @param host * The host name to be associated with the given IP. * @param ips * array of IP addresses to be resolved by this DNS overrider to the given * host name. */ public void add(final String host, final InetAddress... ips) { Args.notNull(host, "Host name"); Args.notNull(ips, "Array of IP addresses"); dnsMap.put(host, ips); } /** * {@inheritDoc} */ public InetAddress[] resolve(final String host) throws UnknownHostException { final InetAddress[] resolvedAddresses = dnsMap.get(host); if (log.isInfoEnabled()) { log.info("Resolving " + host + " to " + Arrays.deepToString(resolvedAddresses)); } if(resolvedAddresses == null){ throw new UnknownHostException(host + " cannot be resolved"); } return resolvedAddresses; } } ././@LongLink0100644 0000000 0000000 00000000147 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/LoggingInputStream.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/LoggingInputStream.ja0100644 0000000 0000000 00000007734 12301751706 032423 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import org.apache.http.annotation.NotThreadSafe; import java.io.IOException; import java.io.InputStream; /** * Internal class. * * @since 4.3 */ @NotThreadSafe class LoggingInputStream extends InputStream { private final InputStream in; private final Wire wire; public LoggingInputStream(final InputStream in, final Wire wire) { super(); this.in = in; this.wire = wire; } @Override public int read() throws IOException { try { final int b = in.read(); if (b == -1) { wire.input("end of stream"); } else { wire.input(b); } return b; } catch (IOException ex) { wire.input("[read] I/O error: " + ex.getMessage()); throw ex; } } @Override public int read(final byte[] b) throws IOException { try { final int bytesRead = in.read(b); if (bytesRead == -1) { wire.input("end of stream"); } else if (bytesRead > 0) { wire.input(b, 0, bytesRead); } return bytesRead; } catch (IOException ex) { wire.input("[read] I/O error: " + ex.getMessage()); throw ex; } } @Override public int read(final byte[] b, final int off, final int len) throws IOException { try { final int bytesRead = in.read(b, off, len); if (bytesRead == -1) { wire.input("end of stream"); } else if (bytesRead > 0) { wire.input(b, off, bytesRead); } return bytesRead; } catch (IOException ex) { wire.input("[read] I/O error: " + ex.getMessage()); throw ex; } } @Override public long skip(final long n) throws IOException { try { return super.skip(n); } catch (IOException ex) { wire.input("[skip] I/O error: " + ex.getMessage()); throw ex; } } @Override public int available() throws IOException { try { return in.available(); } catch (IOException ex) { wire.input("[available] I/O error : " + ex.getMessage()); throw ex; } } @Override public void mark(final int readlimit) { super.mark(readlimit); } @Override public void reset() throws IOException { super.reset(); } @Override public boolean markSupported() { return false; } @Override public void close() throws IOException { try { in.close(); } catch (IOException ex) { wire.input("[close] I/O error: " + ex.getMessage()); throw ex; } } } ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/LoggingManagedHttpClientConnection.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/LoggingManagedHttpCli0100644 0000000 0000000 00000011467 12301751706 032401 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import org.apache.commons.logging.Log; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.config.MessageConstraints; import org.apache.http.entity.ContentLengthStrategy; import org.apache.http.io.HttpMessageParserFactory; import org.apache.http.io.HttpMessageWriterFactory; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; @NotThreadSafe class LoggingManagedHttpClientConnection extends DefaultManagedHttpClientConnection { private final Log log; private final Log headerlog; private final Wire wire; public LoggingManagedHttpClientConnection( final String id, final Log log, final Log headerlog, final Log wirelog, final int buffersize, final int fragmentSizeHint, final CharsetDecoder chardecoder, final CharsetEncoder charencoder, final MessageConstraints constraints, final ContentLengthStrategy incomingContentStrategy, final ContentLengthStrategy outgoingContentStrategy, final HttpMessageWriterFactory requestWriterFactory, final HttpMessageParserFactory responseParserFactory) { super(id, buffersize, fragmentSizeHint, chardecoder, charencoder, constraints, incomingContentStrategy, outgoingContentStrategy, requestWriterFactory, responseParserFactory); this.log = log; this.headerlog = headerlog; this.wire = new Wire(wirelog, id); } @Override public void close() throws IOException { if (this.log.isDebugEnabled()) { this.log.debug(getId() + ": Close connection"); } super.close(); } @Override public void shutdown() throws IOException { if (this.log.isDebugEnabled()) { this.log.debug(getId() + ": Shutdown connection"); } super.shutdown(); } @Override protected InputStream getSocketInputStream(final Socket socket) throws IOException { InputStream in = super.getSocketInputStream(socket); if (this.wire.enabled()) { in = new LoggingInputStream(in, this.wire); } return in; } @Override protected OutputStream getSocketOutputStream(final Socket socket) throws IOException { OutputStream out = super.getSocketOutputStream(socket); if (this.wire.enabled()) { out = new LoggingOutputStream(out, this.wire); } return out; } @Override protected void onResponseReceived(final HttpResponse response) { if (response != null && this.headerlog.isDebugEnabled()) { this.headerlog.debug(getId() + " << " + response.getStatusLine().toString()); final Header[] headers = response.getAllHeaders(); for (final Header header : headers) { this.headerlog.debug(getId() + " << " + header.toString()); } } } @Override protected void onRequestSubmitted(final HttpRequest request) { if (request != null && this.headerlog.isDebugEnabled()) { this.headerlog.debug(getId() + " >> " + request.getRequestLine().toString()); final Header[] headers = request.getAllHeaders(); for (final Header header : headers) { this.headerlog.debug(getId() + " >> " + header.toString()); } } } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/LoggingOutputStream.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/LoggingOutputStream.j0100644 0000000 0000000 00000005662 12301751706 032461 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import org.apache.http.annotation.NotThreadSafe; import java.io.IOException; import java.io.OutputStream; /** * Internal class. * * @since 4.3 */ @NotThreadSafe class LoggingOutputStream extends OutputStream { private final OutputStream out; private final Wire wire; public LoggingOutputStream(final OutputStream out, final Wire wire) { super(); this.out = out; this.wire = wire; } @Override public void write(final int b) throws IOException { try { wire.output(b); } catch (IOException ex) { wire.output("[write] I/O error: " + ex.getMessage()); throw ex; } } @Override public void write(final byte[] b) throws IOException { try { wire.output(b); out.write(b); } catch (IOException ex) { wire.output("[write] I/O error: " + ex.getMessage()); throw ex; } } @Override public void write(final byte[] b, final int off, final int len) throws IOException { try { wire.output(b, off, len); out.write(b, off, len); } catch (IOException ex) { wire.output("[write] I/O error: " + ex.getMessage()); throw ex; } } @Override public void flush() throws IOException { try { out.flush(); } catch (IOException ex) { wire.output("[flush] I/O error: " + ex.getMessage()); throw ex; } } @Override public void close() throws IOException { try { out.close(); } catch (IOException ex) { wire.output("[close] I/O error: " + ex.getMessage()); throw ex; } } } ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/ManagedHttpClientConnectionFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/ManagedHttpClientConn0100644 0000000 0000000 00000012204 12301751706 032405 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.nio.charset.CodingErrorAction; import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.annotation.Immutable; import org.apache.http.config.ConnectionConfig; import org.apache.http.conn.HttpConnectionFactory; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.impl.io.DefaultHttpRequestWriterFactory; import org.apache.http.io.HttpMessageParserFactory; import org.apache.http.io.HttpMessageWriterFactory; /** * Factory for {@link ManagedHttpClientConnection} instances. * @since 4.3 */ @Immutable public class ManagedHttpClientConnectionFactory implements HttpConnectionFactory { private static final AtomicLong COUNTER = new AtomicLong(); public static final ManagedHttpClientConnectionFactory INSTANCE = new ManagedHttpClientConnectionFactory(); private final Log log = LogFactory.getLog(DefaultManagedHttpClientConnection.class); private final Log headerlog = LogFactory.getLog("org.apache.http.headers"); private final Log wirelog = LogFactory.getLog("org.apache.http.wire"); private final HttpMessageWriterFactory requestWriterFactory; private final HttpMessageParserFactory responseParserFactory; public ManagedHttpClientConnectionFactory( final HttpMessageWriterFactory requestWriterFactory, final HttpMessageParserFactory responseParserFactory) { super(); this.requestWriterFactory = requestWriterFactory != null ? requestWriterFactory : DefaultHttpRequestWriterFactory.INSTANCE; this.responseParserFactory = responseParserFactory != null ? responseParserFactory : DefaultHttpResponseParserFactory.INSTANCE; } public ManagedHttpClientConnectionFactory( final HttpMessageParserFactory responseParserFactory) { this(null, responseParserFactory); } public ManagedHttpClientConnectionFactory() { this(null, null); } public ManagedHttpClientConnection create(final HttpRoute route, final ConnectionConfig config) { final ConnectionConfig cconfig = config != null ? config : ConnectionConfig.DEFAULT; CharsetDecoder chardecoder = null; CharsetEncoder charencoder = null; final Charset charset = cconfig.getCharset(); final CodingErrorAction malformedInputAction = cconfig.getMalformedInputAction() != null ? cconfig.getMalformedInputAction() : CodingErrorAction.REPORT; final CodingErrorAction unmappableInputAction = cconfig.getUnmappableInputAction() != null ? cconfig.getUnmappableInputAction() : CodingErrorAction.REPORT; if (charset != null) { chardecoder = charset.newDecoder(); chardecoder.onMalformedInput(malformedInputAction); chardecoder.onUnmappableCharacter(unmappableInputAction); charencoder = charset.newEncoder(); charencoder.onMalformedInput(malformedInputAction); charencoder.onUnmappableCharacter(unmappableInputAction); } final String id = "http-outgoing-" + Long.toString(COUNTER.getAndIncrement()); return new LoggingManagedHttpClientConnection( id, log, headerlog, wirelog, cconfig.getBufferSize(), cconfig.getFragmentSizeHint(), chardecoder, charencoder, cconfig.getMessageConstraints(), null, null, requestWriterFactory, responseParserFactory); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/package-info.java0100644 0000000 0000000 00000002425 12301751706 031504 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Default implementations of client connection management * functions. */ package org.apache.http.impl.conn; ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/PoolingHttpClientConnectionManager.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/PoolingHttpClientConn0100644 0000000 0000000 00000047147 12301751706 032476 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.Closeable; import java.io.IOException; import java.net.InetSocketAddress; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpClientConnection; import org.apache.http.HttpHost; import org.apache.http.annotation.ThreadSafe; import org.apache.http.config.ConnectionConfig; import org.apache.http.config.Lookup; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.config.SocketConfig; import org.apache.http.conn.ConnectionPoolTimeoutException; import org.apache.http.conn.ConnectionRequest; import org.apache.http.conn.DnsResolver; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.conn.HttpConnectionFactory; import org.apache.http.conn.SchemePortResolver; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.pool.ConnFactory; import org.apache.http.pool.ConnPoolControl; import org.apache.http.pool.PoolStats; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.Asserts; /** * ClientConnectionPoolManager maintains a pool of * {@link HttpClientConnection}s and is able to service connection requests * from multiple execution threads. Connections are pooled on a per route * basis. A request for a route which already the manager has persistent * connections for available in the pool will be services by leasing * a connection from the pool rather than creating a brand new connection. *

* ClientConnectionPoolManager maintains a maximum limit of connection * on a per route basis and in total. Per default this implementation will * create no more than than 2 concurrent connections per given route * and no more 20 connections in total. For many real-world applications * these limits may prove too constraining, especially if they use HTTP * as a transport protocol for their services. Connection limits, however, * can be adjusted using {@link ConnPoolControl} methods. * * @since 4.3 */ @ThreadSafe public class PoolingHttpClientConnectionManager implements HttpClientConnectionManager, ConnPoolControl, Closeable { private final Log log = LogFactory.getLog(getClass()); private final ConfigData configData; private final CPool pool; private final HttpClientConnectionOperator connectionOperator; private static Registry getDefaultRegistry() { return RegistryBuilder.create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", SSLConnectionSocketFactory.getSocketFactory()) .build(); } public PoolingHttpClientConnectionManager() { this(getDefaultRegistry()); } public PoolingHttpClientConnectionManager(final long timeToLive, final TimeUnit tunit) { this(getDefaultRegistry(), null, null ,null, timeToLive, tunit); } public PoolingHttpClientConnectionManager( final Registry socketFactoryRegistry) { this(socketFactoryRegistry, null, null); } public PoolingHttpClientConnectionManager( final Registry socketFactoryRegistry, final DnsResolver dnsResolver) { this(socketFactoryRegistry, null, dnsResolver); } public PoolingHttpClientConnectionManager( final Registry socketFactoryRegistry, final HttpConnectionFactory connFactory) { this(socketFactoryRegistry, connFactory, null); } public PoolingHttpClientConnectionManager( final HttpConnectionFactory connFactory) { this(getDefaultRegistry(), connFactory, null); } public PoolingHttpClientConnectionManager( final Registry socketFactoryRegistry, final HttpConnectionFactory connFactory, final DnsResolver dnsResolver) { this(socketFactoryRegistry, connFactory, null, dnsResolver, -1, TimeUnit.MILLISECONDS); } public PoolingHttpClientConnectionManager( final Registry socketFactoryRegistry, final HttpConnectionFactory connFactory, final SchemePortResolver schemePortResolver, final DnsResolver dnsResolver, final long timeToLive, final TimeUnit tunit) { super(); this.configData = new ConfigData(); this.pool = new CPool( new InternalConnectionFactory(this.configData, connFactory), 2, 20, timeToLive, tunit); this.connectionOperator = new HttpClientConnectionOperator( socketFactoryRegistry, schemePortResolver, dnsResolver); } PoolingHttpClientConnectionManager( final CPool pool, final Lookup socketFactoryRegistry, final SchemePortResolver schemePortResolver, final DnsResolver dnsResolver) { super(); this.configData = new ConfigData(); this.pool = pool; this.connectionOperator = new HttpClientConnectionOperator( socketFactoryRegistry, schemePortResolver, dnsResolver); } @Override protected void finalize() throws Throwable { try { shutdown(); } finally { super.finalize(); } } public void close() { shutdown(); } private String format(final HttpRoute route, final Object state) { final StringBuilder buf = new StringBuilder(); buf.append("[route: ").append(route).append("]"); if (state != null) { buf.append("[state: ").append(state).append("]"); } return buf.toString(); } private String formatStats(final HttpRoute route) { final StringBuilder buf = new StringBuilder(); final PoolStats totals = this.pool.getTotalStats(); final PoolStats stats = this.pool.getStats(route); buf.append("[total kept alive: ").append(totals.getAvailable()).append("; "); buf.append("route allocated: ").append(stats.getLeased() + stats.getAvailable()); buf.append(" of ").append(stats.getMax()).append("; "); buf.append("total allocated: ").append(totals.getLeased() + totals.getAvailable()); buf.append(" of ").append(totals.getMax()).append("]"); return buf.toString(); } private String format(final CPoolEntry entry) { final StringBuilder buf = new StringBuilder(); buf.append("[id: ").append(entry.getId()).append("]"); buf.append("[route: ").append(entry.getRoute()).append("]"); final Object state = entry.getState(); if (state != null) { buf.append("[state: ").append(state).append("]"); } return buf.toString(); } public ConnectionRequest requestConnection( final HttpRoute route, final Object state) { Args.notNull(route, "HTTP route"); if (this.log.isDebugEnabled()) { this.log.debug("Connection request: " + format(route, state) + formatStats(route)); } final Future future = this.pool.lease(route, state, null); return new ConnectionRequest() { public boolean cancel() { return future.cancel(true); } public HttpClientConnection get( final long timeout, final TimeUnit tunit) throws InterruptedException, ExecutionException, ConnectionPoolTimeoutException { return leaseConnection(future, timeout, tunit); } }; } protected HttpClientConnection leaseConnection( final Future future, final long timeout, final TimeUnit tunit) throws InterruptedException, ExecutionException, ConnectionPoolTimeoutException { final CPoolEntry entry; try { entry = future.get(timeout, tunit); if (entry == null || future.isCancelled()) { throw new InterruptedException(); } Asserts.check(entry.getConnection() != null, "Pool entry with no connection"); if (this.log.isDebugEnabled()) { this.log.debug("Connection leased: " + format(entry) + formatStats(entry.getRoute())); } return CPoolProxy.newProxy(entry); } catch (final TimeoutException ex) { throw new ConnectionPoolTimeoutException("Timeout waiting for connection from pool"); } } public void releaseConnection( final HttpClientConnection managedConn, final Object state, final long keepalive, final TimeUnit tunit) { Args.notNull(managedConn, "Managed connection"); synchronized (managedConn) { final CPoolEntry entry = CPoolProxy.detach(managedConn); if (entry == null) { return; } final ManagedHttpClientConnection conn = entry.getConnection(); try { if (conn.isOpen()) { entry.setState(state); entry.updateExpiry(keepalive, tunit != null ? tunit : TimeUnit.MILLISECONDS); if (this.log.isDebugEnabled()) { final String s; if (keepalive > 0) { s = "for " + (double) keepalive / 1000 + " seconds"; } else { s = "indefinitely"; } this.log.debug("Connection " + format(entry) + " can be kept alive " + s); } } } finally { this.pool.release(entry, conn.isOpen() && entry.isRouteComplete()); if (this.log.isDebugEnabled()) { this.log.debug("Connection released: " + format(entry) + formatStats(entry.getRoute())); } } } } public void connect( final HttpClientConnection managedConn, final HttpRoute route, final int connectTimeout, final HttpContext context) throws IOException { Args.notNull(managedConn, "Managed Connection"); Args.notNull(route, "HTTP route"); final ManagedHttpClientConnection conn; synchronized (managedConn) { final CPoolEntry entry = CPoolProxy.getPoolEntry(managedConn); conn = entry.getConnection(); } final HttpHost host; if (route.getProxyHost() != null) { host = route.getProxyHost(); } else { host = route.getTargetHost(); } final InetSocketAddress localAddress = route.getLocalSocketAddress(); SocketConfig socketConfig = this.configData.getSocketConfig(host); if (socketConfig == null) { socketConfig = this.configData.getDefaultSocketConfig(); } if (socketConfig == null) { socketConfig = SocketConfig.DEFAULT; } this.connectionOperator.connect( conn, host, localAddress, connectTimeout, socketConfig, context); } public void upgrade( final HttpClientConnection managedConn, final HttpRoute route, final HttpContext context) throws IOException { Args.notNull(managedConn, "Managed Connection"); Args.notNull(route, "HTTP route"); final ManagedHttpClientConnection conn; synchronized (managedConn) { final CPoolEntry entry = CPoolProxy.getPoolEntry(managedConn); conn = entry.getConnection(); } this.connectionOperator.upgrade(conn, route.getTargetHost(), context); } public void routeComplete( final HttpClientConnection managedConn, final HttpRoute route, final HttpContext context) throws IOException { Args.notNull(managedConn, "Managed Connection"); Args.notNull(route, "HTTP route"); synchronized (managedConn) { final CPoolEntry entry = CPoolProxy.getPoolEntry(managedConn); entry.markRouteComplete(); } } public void shutdown() { this.log.debug("Connection manager is shutting down"); try { this.pool.shutdown(); } catch (final IOException ex) { this.log.debug("I/O exception shutting down connection manager", ex); } this.log.debug("Connection manager shut down"); } public void closeIdleConnections(final long idleTimeout, final TimeUnit tunit) { if (this.log.isDebugEnabled()) { this.log.debug("Closing connections idle longer than " + idleTimeout + " " + tunit); } this.pool.closeIdle(idleTimeout, tunit); } public void closeExpiredConnections() { this.log.debug("Closing expired connections"); this.pool.closeExpired(); } public int getMaxTotal() { return this.pool.getMaxTotal(); } public void setMaxTotal(final int max) { this.pool.setMaxTotal(max); } public int getDefaultMaxPerRoute() { return this.pool.getDefaultMaxPerRoute(); } public void setDefaultMaxPerRoute(final int max) { this.pool.setDefaultMaxPerRoute(max); } public int getMaxPerRoute(final HttpRoute route) { return this.pool.getMaxPerRoute(route); } public void setMaxPerRoute(final HttpRoute route, final int max) { this.pool.setMaxPerRoute(route, max); } public PoolStats getTotalStats() { return this.pool.getTotalStats(); } public PoolStats getStats(final HttpRoute route) { return this.pool.getStats(route); } public SocketConfig getDefaultSocketConfig() { return this.configData.getDefaultSocketConfig(); } public void setDefaultSocketConfig(final SocketConfig defaultSocketConfig) { this.configData.setDefaultSocketConfig(defaultSocketConfig); } public ConnectionConfig getDefaultConnectionConfig() { return this.configData.getDefaultConnectionConfig(); } public void setDefaultConnectionConfig(final ConnectionConfig defaultConnectionConfig) { this.configData.setDefaultConnectionConfig(defaultConnectionConfig); } public SocketConfig getSocketConfig(final HttpHost host) { return this.configData.getSocketConfig(host); } public void setSocketConfig(final HttpHost host, final SocketConfig socketConfig) { this.configData.setSocketConfig(host, socketConfig); } public ConnectionConfig getConnectionConfig(final HttpHost host) { return this.configData.getConnectionConfig(host); } public void setConnectionConfig(final HttpHost host, final ConnectionConfig connectionConfig) { this.configData.setConnectionConfig(host, connectionConfig); } static class ConfigData { private final Map socketConfigMap; private final Map connectionConfigMap; private volatile SocketConfig defaultSocketConfig; private volatile ConnectionConfig defaultConnectionConfig; ConfigData() { super(); this.socketConfigMap = new ConcurrentHashMap(); this.connectionConfigMap = new ConcurrentHashMap(); } public SocketConfig getDefaultSocketConfig() { return this.defaultSocketConfig; } public void setDefaultSocketConfig(final SocketConfig defaultSocketConfig) { this.defaultSocketConfig = defaultSocketConfig; } public ConnectionConfig getDefaultConnectionConfig() { return this.defaultConnectionConfig; } public void setDefaultConnectionConfig(final ConnectionConfig defaultConnectionConfig) { this.defaultConnectionConfig = defaultConnectionConfig; } public SocketConfig getSocketConfig(final HttpHost host) { return this.socketConfigMap.get(host); } public void setSocketConfig(final HttpHost host, final SocketConfig socketConfig) { this.socketConfigMap.put(host, socketConfig); } public ConnectionConfig getConnectionConfig(final HttpHost host) { return this.connectionConfigMap.get(host); } public void setConnectionConfig(final HttpHost host, final ConnectionConfig connectionConfig) { this.connectionConfigMap.put(host, connectionConfig); } } static class InternalConnectionFactory implements ConnFactory { private final ConfigData configData; private final HttpConnectionFactory connFactory; InternalConnectionFactory( final ConfigData configData, final HttpConnectionFactory connFactory) { super(); this.configData = configData != null ? configData : new ConfigData(); this.connFactory = connFactory != null ? connFactory : ManagedHttpClientConnectionFactory.INSTANCE; } public ManagedHttpClientConnection create(final HttpRoute route) throws IOException { ConnectionConfig config = null; if (route.getProxyHost() != null) { config = this.configData.getConnectionConfig(route.getProxyHost()); } if (config == null) { config = this.configData.getConnectionConfig(route.getTargetHost()); } if (config == null) { config = this.configData.getDefaultConnectionConfig(); } if (config == null) { config = ConnectionConfig.DEFAULT; } return this.connFactory.create(route, config); } } } ././@LongLink0100644 0000000 0000000 00000000155 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/SystemDefaultDnsResolver.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/SystemDefaultDnsResol0100644 0000000 0000000 00000003304 12301751706 032500 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.net.InetAddress; import java.net.UnknownHostException; import org.apache.http.conn.DnsResolver; /** * DNS resolver that uses the default OS implementation for resolving host names. * * @since 4.2 */ public class SystemDefaultDnsResolver implements DnsResolver { public static final SystemDefaultDnsResolver INSTANCE = new SystemDefaultDnsResolver(); public InetAddress[] resolve(final String host) throws UnknownHostException { return InetAddress.getAllByName(host); } } ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/SystemDefaultRoutePlanner.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/SystemDefaultRoutePla0100644 0000000 0000000 00000011332 12301751706 032502 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.ProxySelector; import java.net.URI; import java.net.URISyntaxException; import java.util.List; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.annotation.Immutable; import org.apache.http.conn.SchemePortResolver; import org.apache.http.protocol.HttpContext; /** * {@link org.apache.http.conn.routing.HttpRoutePlanner} implementation * based on {@link ProxySelector}. By default, this class will pick up * the proxy settings of the JVM, either from system properties * or from the browser running the application. * * @since 4.3 */ @Immutable public class SystemDefaultRoutePlanner extends DefaultRoutePlanner { private final ProxySelector proxySelector; public SystemDefaultRoutePlanner( final SchemePortResolver schemePortResolver, final ProxySelector proxySelector) { super(schemePortResolver); this.proxySelector = proxySelector != null ? proxySelector : ProxySelector.getDefault(); } public SystemDefaultRoutePlanner(final ProxySelector proxySelector) { this(null, proxySelector); } @Override protected HttpHost determineProxy( final HttpHost target, final HttpRequest request, final HttpContext context) throws HttpException { final URI targetURI; try { targetURI = new URI(target.toURI()); } catch (final URISyntaxException ex) { throw new HttpException("Cannot convert host to URI: " + target, ex); } final List proxies = this.proxySelector.select(targetURI); final Proxy p = chooseProxy(proxies); HttpHost result = null; if (p.type() == Proxy.Type.HTTP) { // convert the socket address to an HttpHost if (!(p.address() instanceof InetSocketAddress)) { throw new HttpException("Unable to handle non-Inet proxy address: " + p.address()); } final InetSocketAddress isa = (InetSocketAddress) p.address(); // assume default scheme (http) result = new HttpHost(getHost(isa), isa.getPort()); } return result; } private String getHost(final InetSocketAddress isa) { //@@@ Will this work with literal IPv6 addresses, or do we //@@@ need to wrap these in [] for the string representation? //@@@ Having it in this method at least allows for easy workarounds. return isa.isUnresolved() ? isa.getHostName() : isa.getAddress().getHostAddress(); } private Proxy chooseProxy(final List proxies) { Proxy result = null; // check the list for one we can use for (int i=0; (result == null) && (i < proxies.size()); i++) { final Proxy p = proxies.get(i); switch (p.type()) { case DIRECT: case HTTP: result = p; break; case SOCKS: // SOCKS hosts are not handled on the route level. // The socket may make use of the SOCKS host though. break; } } if (result == null) { //@@@ log as warning or info that only a socks proxy is available? // result can only be null if all proxies are socks proxies // socks proxies are not handled on the route planning level result = Proxy.NO_PROXY; } return result; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/conn/Wire.java0100644 0000000 0000000 00000010574 12301751706 030072 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import org.apache.commons.logging.Log; import org.apache.http.annotation.Immutable; import org.apache.http.util.Args; /** * Logs data to the wire LOG. * TODO: make package private. Should not be part of the public API. * * @since 4.0 */ @Immutable public class Wire { private final Log log; private final String id; /** * @since 4.3 */ public Wire(final Log log, final String id) { this.log = log; this.id = id; } public Wire(final Log log) { this(log, ""); } private void wire(final String header, final InputStream instream) throws IOException { final StringBuilder buffer = new StringBuilder(); int ch; while ((ch = instream.read()) != -1) { if (ch == 13) { buffer.append("[\\r]"); } else if (ch == 10) { buffer.append("[\\n]\""); buffer.insert(0, "\""); buffer.insert(0, header); log.debug(id + " " + buffer.toString()); buffer.setLength(0); } else if ((ch < 32) || (ch > 127)) { buffer.append("[0x"); buffer.append(Integer.toHexString(ch)); buffer.append("]"); } else { buffer.append((char) ch); } } if (buffer.length() > 0) { buffer.append('\"'); buffer.insert(0, '\"'); buffer.insert(0, header); log.debug(id + " " + buffer.toString()); } } public boolean enabled() { return log.isDebugEnabled(); } public void output(final InputStream outstream) throws IOException { Args.notNull(outstream, "Output"); wire(">> ", outstream); } public void input(final InputStream instream) throws IOException { Args.notNull(instream, "Input"); wire("<< ", instream); } public void output(final byte[] b, final int off, final int len) throws IOException { Args.notNull(b, "Output"); wire(">> ", new ByteArrayInputStream(b, off, len)); } public void input(final byte[] b, final int off, final int len) throws IOException { Args.notNull(b, "Input"); wire("<< ", new ByteArrayInputStream(b, off, len)); } public void output(final byte[] b) throws IOException { Args.notNull(b, "Output"); wire(">> ", new ByteArrayInputStream(b)); } public void input(final byte[] b) throws IOException { Args.notNull(b, "Input"); wire("<< ", new ByteArrayInputStream(b)); } public void output(final int b) throws IOException { output(new byte[] {(byte) b}); } public void input(final int b) throws IOException { input(new byte[] {(byte) b}); } public void output(final String s) throws IOException { Args.notNull(s, "Output"); output(s.getBytes()); } public void input(final String s) throws IOException { Args.notNull(s, "Input"); input(s.getBytes()); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/0040755 0000000 0000000 00000000000 12301751705 026630 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/AbstractCookieAttributeHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/AbstractCookieAttri0100644 0000000 0000000 00000003507 12301751705 032456 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; /** * * @since 4.0 */ @Immutable public abstract class AbstractCookieAttributeHandler implements CookieAttributeHandler { public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { // Do nothing } public boolean match(final Cookie cookie, final CookieOrigin origin) { // Always match return true; } } ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/AbstractCookieSpec.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/AbstractCookieSpec.0100644 0000000 0000000 00000007062 12301751705 032343 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieSpec; import org.apache.http.util.Args; /** * Abstract cookie specification which can delegate the job of parsing, * validation or matching cookie attributes to a number of arbitrary * {@link CookieAttributeHandler}s. * * * @since 4.0 */ @NotThreadSafe // HashMap is not thread-safe public abstract class AbstractCookieSpec implements CookieSpec { /** * Stores attribute name -> attribute handler mappings */ private final Map attribHandlerMap; /** * Default constructor * */ public AbstractCookieSpec() { super(); this.attribHandlerMap = new HashMap(10); } public void registerAttribHandler( final String name, final CookieAttributeHandler handler) { Args.notNull(name, "Attribute name"); Args.notNull(handler, "Attribute handler"); this.attribHandlerMap.put(name, handler); } /** * Finds an attribute handler {@link CookieAttributeHandler} for the * given attribute. Returns null if no attribute handler is * found for the specified attribute. * * @param name attribute name. e.g. Domain, Path, etc. * @return an attribute handler or null */ protected CookieAttributeHandler findAttribHandler(final String name) { return this.attribHandlerMap.get(name); } /** * Gets attribute handler {@link CookieAttributeHandler} for the * given attribute. * * @param name attribute name. e.g. Domain, Path, etc. * @throws IllegalStateException if handler not found for the * specified attribute. */ protected CookieAttributeHandler getAttribHandler(final String name) { final CookieAttributeHandler handler = findAttribHandler(name); if (handler == null) { throw new IllegalStateException("Handler not registered for " + name + " attribute."); } else { return handler; } } protected Collection getAttribHandlers() { return this.attribHandlerMap.values(); } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicClientCookie.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicClientCookie.j0100644 0000000 0000000 00000022535 12301751705 032321 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.io.Serializable; import java.util.Date; import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; /** * Default implementation of {@link SetCookie}. * * @since 4.0 */ @NotThreadSafe public class BasicClientCookie implements SetCookie, ClientCookie, Cloneable, Serializable { private static final long serialVersionUID = -3869795591041535538L; /** * Default Constructor taking a name and a value. The value may be null. * * @param name The name. * @param value The value. */ public BasicClientCookie(final String name, final String value) { super(); Args.notNull(name, "Name"); this.name = name; this.attribs = new HashMap(); this.value = value; } /** * Returns the name. * * @return String name The name */ public String getName() { return this.name; } /** * Returns the value. * * @return String value The current value. */ public String getValue() { return this.value; } /** * Sets the value * * @param value */ public void setValue(final String value) { this.value = value; } /** * Returns the comment describing the purpose of this cookie, or * null if no such comment has been defined. * * @return comment * * @see #setComment(String) */ public String getComment() { return cookieComment; } /** * If a user agent (web browser) presents this cookie to a user, the * cookie's purpose will be described using this comment. * * @param comment * * @see #getComment() */ public void setComment(final String comment) { cookieComment = comment; } /** * Returns null. Cookies prior to RFC2965 do not set this attribute */ public String getCommentURL() { return null; } /** * Returns the expiration {@link Date} of the cookie, or null * if none exists. *

Note: the object returned by this method is * considered immutable. Changing it (e.g. using setTime()) could result * in undefined behaviour. Do so at your peril.

* @return Expiration {@link Date}, or null. * * @see #setExpiryDate(java.util.Date) * */ public Date getExpiryDate() { return cookieExpiryDate; } /** * Sets expiration date. *

Note: the object returned by this method is considered * immutable. Changing it (e.g. using setTime()) could result in undefined * behaviour. Do so at your peril.

* * @param expiryDate the {@link Date} after which this cookie is no longer valid. * * @see #getExpiryDate * */ public void setExpiryDate (final Date expiryDate) { cookieExpiryDate = expiryDate; } /** * Returns false if the cookie should be discarded at the end * of the "session"; true otherwise. * * @return false if the cookie should be discarded at the end * of the "session"; true otherwise */ public boolean isPersistent() { return (null != cookieExpiryDate); } /** * Returns domain attribute of the cookie. * * @return the value of the domain attribute * * @see #setDomain(java.lang.String) */ public String getDomain() { return cookieDomain; } /** * Sets the domain attribute. * * @param domain The value of the domain attribute * * @see #getDomain */ public void setDomain(final String domain) { if (domain != null) { cookieDomain = domain.toLowerCase(Locale.ENGLISH); } else { cookieDomain = null; } } /** * Returns the path attribute of the cookie * * @return The value of the path attribute. * * @see #setPath(java.lang.String) */ public String getPath() { return cookiePath; } /** * Sets the path attribute. * * @param path The value of the path attribute * * @see #getPath * */ public void setPath(final String path) { cookiePath = path; } /** * @return true if this cookie should only be sent over secure connections. * @see #setSecure(boolean) */ public boolean isSecure() { return isSecure; } /** * Sets the secure attribute of the cookie. *

* When true the cookie should only be sent * using a secure protocol (https). This should only be set when * the cookie's originating server used a secure protocol to set the * cookie's value. * * @param secure The value of the secure attribute * * @see #isSecure() */ public void setSecure (final boolean secure) { isSecure = secure; } /** * Returns null. Cookies prior to RFC2965 do not set this attribute */ public int[] getPorts() { return null; } /** * Returns the version of the cookie specification to which this * cookie conforms. * * @return the version of the cookie. * * @see #setVersion(int) * */ public int getVersion() { return cookieVersion; } /** * Sets the version of the cookie specification to which this * cookie conforms. * * @param version the version of the cookie. * * @see #getVersion */ public void setVersion(final int version) { cookieVersion = version; } /** * Returns true if this cookie has expired. * @param date Current time * * @return true if the cookie has expired. */ public boolean isExpired(final Date date) { Args.notNull(date, "Date"); return (cookieExpiryDate != null && cookieExpiryDate.getTime() <= date.getTime()); } public void setAttribute(final String name, final String value) { this.attribs.put(name, value); } public String getAttribute(final String name) { return this.attribs.get(name); } public boolean containsAttribute(final String name) { return this.attribs.get(name) != null; } @Override public Object clone() throws CloneNotSupportedException { final BasicClientCookie clone = (BasicClientCookie) super.clone(); clone.attribs = new HashMap(this.attribs); return clone; } @Override public String toString() { final StringBuilder buffer = new StringBuilder(); buffer.append("[version: "); buffer.append(Integer.toString(this.cookieVersion)); buffer.append("]"); buffer.append("[name: "); buffer.append(this.name); buffer.append("]"); buffer.append("[value: "); buffer.append(this.value); buffer.append("]"); buffer.append("[domain: "); buffer.append(this.cookieDomain); buffer.append("]"); buffer.append("[path: "); buffer.append(this.cookiePath); buffer.append("]"); buffer.append("[expiry: "); buffer.append(this.cookieExpiryDate); buffer.append("]"); return buffer.toString(); } // ----------------------------------------------------- Instance Variables /** Cookie name */ private final String name; /** Cookie attributes as specified by the origin server */ private Map attribs; /** Cookie value */ private String value; /** Comment attribute. */ private String cookieComment; /** Domain attribute. */ private String cookieDomain; /** Expiration {@link Date}. */ private Date cookieExpiryDate; /** Path attribute. */ private String cookiePath; /** My secure flag. */ private boolean isSecure; /** The version of the cookie specification I was created from. */ private int cookieVersion; } ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicClientCookie2.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicClientCookie2.0100644 0000000 0000000 00000005506 12301751705 032230 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Date; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.cookie.SetCookie2; /** * Default implementation of {@link SetCookie2}. * * @since 4.0 */ @NotThreadSafe public class BasicClientCookie2 extends BasicClientCookie implements SetCookie2 { private static final long serialVersionUID = -7744598295706617057L; private String commentURL; private int[] ports; private boolean discard; /** * Default Constructor taking a name and a value. The value may be null. * * @param name The name. * @param value The value. */ public BasicClientCookie2(final String name, final String value) { super(name, value); } @Override public int[] getPorts() { return this.ports; } public void setPorts(final int[] ports) { this.ports = ports; } @Override public String getCommentURL() { return this.commentURL; } public void setCommentURL(final String commentURL) { this.commentURL = commentURL; } public void setDiscard(final boolean discard) { this.discard = discard; } @Override public boolean isPersistent() { return !this.discard && super.isPersistent(); } @Override public boolean isExpired(final Date date) { return this.discard || super.isExpired(date); } @Override public Object clone() throws CloneNotSupportedException { final BasicClientCookie2 clone = (BasicClientCookie2) super.clone(); if (this.ports != null) { clone.ports = this.ports.clone(); } return clone; } } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicCommentHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicCommentHandler0100644 0000000 0000000 00000003344 12301751705 032416 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; /** * * @since 4.0 */ @Immutable public class BasicCommentHandler extends AbstractCookieAttributeHandler { public BasicCommentHandler() { super(); } public void parse(final SetCookie cookie, final String value) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); cookie.setComment(value); } } ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicDomainHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicDomainHandler.0100644 0000000 0000000 00000010564 12301751705 032303 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; /** * * @since 4.0 */ @Immutable public class BasicDomainHandler implements CookieAttributeHandler { public BasicDomainHandler() { super(); } public void parse(final SetCookie cookie, final String value) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); if (value == null) { throw new MalformedCookieException("Missing value for domain attribute"); } if (value.trim().length() == 0) { throw new MalformedCookieException("Blank value for domain attribute"); } cookie.setDomain(value); } public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); // Validate the cookies domain attribute. NOTE: Domains without // any dots are allowed to support hosts on private LANs that don't // have DNS names. Since they have no dots, to domain-match the // request-host and domain must be identical for the cookie to sent // back to the origin-server. final String host = origin.getHost(); String domain = cookie.getDomain(); if (domain == null) { throw new CookieRestrictionViolationException("Cookie domain may not be null"); } if (host.contains(".")) { // Not required to have at least two dots. RFC 2965. // A Set-Cookie2 with Domain=ajax.com will be accepted. // domain must match host if (!host.endsWith(domain)) { if (domain.startsWith(".")) { domain = domain.substring(1, domain.length()); } if (!host.equals(domain)) { throw new CookieRestrictionViolationException( "Illegal domain attribute \"" + domain + "\". Domain of origin: \"" + host + "\""); } } } else { if (!host.equals(domain)) { throw new CookieRestrictionViolationException( "Illegal domain attribute \"" + domain + "\". Domain of origin: \"" + host + "\""); } } } public boolean match(final Cookie cookie, final CookieOrigin origin) { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); final String host = origin.getHost(); String domain = cookie.getDomain(); if (domain == null) { return false; } if (host.equals(domain)) { return true; } if (!domain.startsWith(".")) { domain = '.' + domain; } return host.endsWith(domain) || host.equals(domain.substring(1)); } } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicExpiresHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicExpiresHandler0100644 0000000 0000000 00000004516 12301751705 032435 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Date; import org.apache.http.annotation.Immutable; import org.apache.http.client.utils.DateUtils; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; /** * * @since 4.0 */ @Immutable public class BasicExpiresHandler extends AbstractCookieAttributeHandler { /** Valid date patterns */ private final String[] datepatterns; public BasicExpiresHandler(final String[] datepatterns) { Args.notNull(datepatterns, "Array of date patterns"); this.datepatterns = datepatterns; } public void parse(final SetCookie cookie, final String value) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); if (value == null) { throw new MalformedCookieException("Missing value for expires attribute"); } final Date expiry = DateUtils.parseDate(value, this.datepatterns); if (expiry == null) { throw new MalformedCookieException("Unable to parse expires attribute: " + value); } cookie.setExpiryDate(expiry); } } ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicMaxAgeHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicMaxAgeHandler.0100644 0000000 0000000 00000004456 12301751705 032241 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Date; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; /** * * @since 4.0 */ @Immutable public class BasicMaxAgeHandler extends AbstractCookieAttributeHandler { public BasicMaxAgeHandler() { super(); } public void parse(final SetCookie cookie, final String value) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); if (value == null) { throw new MalformedCookieException("Missing value for max-age attribute"); } final int age; try { age = Integer.parseInt(value); } catch (final NumberFormatException e) { throw new MalformedCookieException ("Invalid max-age attribute: " + value); } if (age < 0) { throw new MalformedCookieException ("Negative max-age attribute: " + value); } cookie.setExpiryDate(new Date(System.currentTimeMillis() + age * 1000L)); } } ././@LongLink0100644 0000000 0000000 00000000147 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicPathHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicPathHandler.ja0100644 0000000 0000000 00000006406 12301751705 032303 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; import org.apache.http.util.TextUtils; /** * * @since 4.0 */ @Immutable public class BasicPathHandler implements CookieAttributeHandler { public BasicPathHandler() { super(); } public void parse( final SetCookie cookie, final String value) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); cookie.setPath(!TextUtils.isBlank(value) ? value : "/"); } public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { if (!match(cookie, origin)) { throw new CookieRestrictionViolationException( "Illegal path attribute \"" + cookie.getPath() + "\". Path of origin: \"" + origin.getPath() + "\""); } } public boolean match(final Cookie cookie, final CookieOrigin origin) { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); final String targetpath = origin.getPath(); String topmostPath = cookie.getPath(); if (topmostPath == null) { topmostPath = "/"; } if (topmostPath.length() > 1 && topmostPath.endsWith("/")) { topmostPath = topmostPath.substring(0, topmostPath.length() - 1); } boolean match = targetpath.startsWith (topmostPath); // if there is a match and these values are not exactly the same we have // to make sure we're not matcing "/foobar" and "/foo" if (match && targetpath.length() != topmostPath.length()) { if (!topmostPath.endsWith("/")) { match = (targetpath.charAt(topmostPath.length()) == '/'); } } return match; } } ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicSecureHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BasicSecureHandler.0100644 0000000 0000000 00000004041 12301751705 032313 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; /** * * @since 4.0 */ @Immutable public class BasicSecureHandler extends AbstractCookieAttributeHandler { public BasicSecureHandler() { super(); } public void parse(final SetCookie cookie, final String value) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); cookie.setSecure(true); } @Override public boolean match(final Cookie cookie, final CookieOrigin origin) { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); return !cookie.isSecure() || origin.isSecure(); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BestMatchSpec.java0100644 0000000 0000000 00000016253 12301751705 032164 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.List; import org.apache.http.FormattedHeader; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SM; import org.apache.http.cookie.SetCookie2; import org.apache.http.message.ParserCursor; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; /** * 'Meta' cookie specification that picks up a cookie policy based on * the format of cookies sent with the HTTP response. * * @since 4.0 */ @NotThreadSafe // CookieSpec fields are @NotThreadSafe public class BestMatchSpec implements CookieSpec { private final String[] datepatterns; private final boolean oneHeader; // Cached values of CookieSpec instances private RFC2965Spec strict; // @NotThreadSafe private RFC2109Spec obsoleteStrict; // @NotThreadSafe private BrowserCompatSpec compat; // @NotThreadSafe public BestMatchSpec(final String[] datepatterns, final boolean oneHeader) { super(); this.datepatterns = datepatterns == null ? null : datepatterns.clone(); this.oneHeader = oneHeader; } public BestMatchSpec() { this(null, false); } private RFC2965Spec getStrict() { if (this.strict == null) { this.strict = new RFC2965Spec(this.datepatterns, this.oneHeader); } return strict; } private RFC2109Spec getObsoleteStrict() { if (this.obsoleteStrict == null) { this.obsoleteStrict = new RFC2109Spec(this.datepatterns, this.oneHeader); } return obsoleteStrict; } private BrowserCompatSpec getCompat() { if (this.compat == null) { this.compat = new BrowserCompatSpec(this.datepatterns); } return compat; } public List parse( final Header header, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(header, "Header"); Args.notNull(origin, "Cookie origin"); HeaderElement[] helems = header.getElements(); boolean versioned = false; boolean netscape = false; for (final HeaderElement helem: helems) { if (helem.getParameterByName("version") != null) { versioned = true; } if (helem.getParameterByName("expires") != null) { netscape = true; } } if (netscape || !versioned) { // Need to parse the header again, because Netscape style cookies do not correctly // support multiple header elements (comma cannot be treated as an element separator) final NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT; final CharArrayBuffer buffer; final ParserCursor cursor; if (header instanceof FormattedHeader) { buffer = ((FormattedHeader) header).getBuffer(); cursor = new ParserCursor( ((FormattedHeader) header).getValuePos(), buffer.length()); } else { final String s = header.getValue(); if (s == null) { throw new MalformedCookieException("Header value is null"); } buffer = new CharArrayBuffer(s.length()); buffer.append(s); cursor = new ParserCursor(0, buffer.length()); } helems = new HeaderElement[] { parser.parseHeader(buffer, cursor) }; return getCompat().parse(helems, origin); } else { if (SM.SET_COOKIE2.equals(header.getName())) { return getStrict().parse(helems, origin); } else { return getObsoleteStrict().parse(helems, origin); } } } public void validate( final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); if (cookie.getVersion() > 0) { if (cookie instanceof SetCookie2) { getStrict().validate(cookie, origin); } else { getObsoleteStrict().validate(cookie, origin); } } else { getCompat().validate(cookie, origin); } } public boolean match(final Cookie cookie, final CookieOrigin origin) { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); if (cookie.getVersion() > 0) { if (cookie instanceof SetCookie2) { return getStrict().match(cookie, origin); } else { return getObsoleteStrict().match(cookie, origin); } } else { return getCompat().match(cookie, origin); } } public List

formatCookies(final List cookies) { Args.notNull(cookies, "List of cookies"); int version = Integer.MAX_VALUE; boolean isSetCookie2 = true; for (final Cookie cookie: cookies) { if (!(cookie instanceof SetCookie2)) { isSetCookie2 = false; } if (cookie.getVersion() < version) { version = cookie.getVersion(); } } if (version > 0) { if (isSetCookie2) { return getStrict().formatCookies(cookies); } else { return getObsoleteStrict().formatCookies(cookies); } } else { return getCompat().formatCookies(cookies); } } public int getVersion() { return getStrict().getVersion(); } public Header getVersionHeader() { return getStrict().getVersionHeader(); } @Override public String toString() { return "best-match"; } } ././@LongLink0100644 0000000 0000000 00000000153 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BestMatchSpecFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BestMatchSpecFactor0100644 0000000 0000000 00000005677 12301751705 032413 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Collection; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.CookieSpecFactory; import org.apache.http.cookie.CookieSpecProvider; import org.apache.http.cookie.params.CookieSpecPNames; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; /** * {@link CookieSpecProvider} implementation that creates and initializes * {@link BestMatchSpec} instances. * * @since 4.0 */ @Immutable @SuppressWarnings("deprecation") public class BestMatchSpecFactory implements CookieSpecFactory, CookieSpecProvider { private final String[] datepatterns; private final boolean oneHeader; public BestMatchSpecFactory(final String[] datepatterns, final boolean oneHeader) { super(); this.datepatterns = datepatterns; this.oneHeader = oneHeader; } public BestMatchSpecFactory() { this(null, false); } public CookieSpec newInstance(final HttpParams params) { if (params != null) { String[] patterns = null; final Collection param = (Collection) params.getParameter( CookieSpecPNames.DATE_PATTERNS); if (param != null) { patterns = new String[param.size()]; patterns = param.toArray(patterns); } final boolean singleHeader = params.getBooleanParameter( CookieSpecPNames.SINGLE_COOKIE_HEADER, false); return new BestMatchSpec(patterns, singleHeader); } else { return new BestMatchSpec(); } } public CookieSpec create(final HttpContext context) { return new BestMatchSpec(this.datepatterns, this.oneHeader); } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BrowserCompatSpec.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BrowserCompatSpec.j0100644 0000000 0000000 00000020536 12301751705 032410 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.ArrayList; import java.util.List; import org.apache.http.FormattedHeader; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.client.utils.DateUtils; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SM; import org.apache.http.message.BasicHeaderElement; import org.apache.http.message.BasicHeaderValueFormatter; import org.apache.http.message.BufferedHeader; import org.apache.http.message.ParserCursor; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; /** * Cookie specification that strives to closely mimic (mis)behavior of * common web browser applications such as Microsoft Internet Explorer * and Mozilla FireFox. * * * @since 4.0 */ @NotThreadSafe // superclass is @NotThreadSafe public class BrowserCompatSpec extends CookieSpecBase { private static final String[] DEFAULT_DATE_PATTERNS = new String[] { DateUtils.PATTERN_RFC1123, DateUtils.PATTERN_RFC1036, DateUtils.PATTERN_ASCTIME, "EEE, dd-MMM-yyyy HH:mm:ss z", "EEE, dd-MMM-yyyy HH-mm-ss z", "EEE, dd MMM yy HH:mm:ss z", "EEE dd-MMM-yyyy HH:mm:ss z", "EEE dd MMM yyyy HH:mm:ss z", "EEE dd-MMM-yyyy HH-mm-ss z", "EEE dd-MMM-yy HH:mm:ss z", "EEE dd MMM yy HH:mm:ss z", "EEE,dd-MMM-yy HH:mm:ss z", "EEE,dd-MMM-yyyy HH:mm:ss z", "EEE, dd-MM-yyyy HH:mm:ss z", }; private final String[] datepatterns; /** Default constructor */ public BrowserCompatSpec(final String[] datepatterns, final BrowserCompatSpecFactory.SecurityLevel securityLevel) { super(); if (datepatterns != null) { this.datepatterns = datepatterns.clone(); } else { this.datepatterns = DEFAULT_DATE_PATTERNS; } switch (securityLevel) { case SECURITYLEVEL_DEFAULT: registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler()); break; case SECURITYLEVEL_IE_MEDIUM: registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler() { @Override public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { // No validation } } ); break; default: throw new RuntimeException("Unknown security level"); } registerAttribHandler(ClientCookie.DOMAIN_ATTR, new BasicDomainHandler()); registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler()); registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler()); registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler()); registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler( this.datepatterns)); registerAttribHandler(ClientCookie.VERSION_ATTR, new BrowserCompatVersionAttributeHandler()); } /** Default constructor */ public BrowserCompatSpec(final String[] datepatterns) { this(datepatterns, BrowserCompatSpecFactory.SecurityLevel.SECURITYLEVEL_DEFAULT); } /** Default constructor */ public BrowserCompatSpec() { this(null, BrowserCompatSpecFactory.SecurityLevel.SECURITYLEVEL_DEFAULT); } public List parse(final Header header, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(header, "Header"); Args.notNull(origin, "Cookie origin"); final String headername = header.getName(); if (!headername.equalsIgnoreCase(SM.SET_COOKIE)) { throw new MalformedCookieException("Unrecognized cookie header '" + header.toString() + "'"); } HeaderElement[] helems = header.getElements(); boolean versioned = false; boolean netscape = false; for (final HeaderElement helem: helems) { if (helem.getParameterByName("version") != null) { versioned = true; } if (helem.getParameterByName("expires") != null) { netscape = true; } } if (netscape || !versioned) { // Need to parse the header again, because Netscape style cookies do not correctly // support multiple header elements (comma cannot be treated as an element separator) final NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT; final CharArrayBuffer buffer; final ParserCursor cursor; if (header instanceof FormattedHeader) { buffer = ((FormattedHeader) header).getBuffer(); cursor = new ParserCursor( ((FormattedHeader) header).getValuePos(), buffer.length()); } else { final String s = header.getValue(); if (s == null) { throw new MalformedCookieException("Header value is null"); } buffer = new CharArrayBuffer(s.length()); buffer.append(s); cursor = new ParserCursor(0, buffer.length()); } helems = new HeaderElement[] { parser.parseHeader(buffer, cursor) }; } return parse(helems, origin); } private static boolean isQuoteEnclosed(final String s) { return s != null && s.startsWith("\"") && s.endsWith("\""); } public List
formatCookies(final List cookies) { Args.notEmpty(cookies, "List of cookies"); final CharArrayBuffer buffer = new CharArrayBuffer(20 * cookies.size()); buffer.append(SM.COOKIE); buffer.append(": "); for (int i = 0; i < cookies.size(); i++) { final Cookie cookie = cookies.get(i); if (i > 0) { buffer.append("; "); } final String cookieName = cookie.getName(); final String cookieValue = cookie.getValue(); if (cookie.getVersion() > 0 && !isQuoteEnclosed(cookieValue)) { BasicHeaderValueFormatter.INSTANCE.formatHeaderElement( buffer, new BasicHeaderElement(cookieName, cookieValue), false); } else { // Netscape style cookies do not support quoted values buffer.append(cookieName); buffer.append("="); if (cookieValue != null) { buffer.append(cookieValue); } } } final List
headers = new ArrayList
(1); headers.add(new BufferedHeader(buffer)); return headers; } public int getVersion() { return 0; } public Header getVersionHeader() { return null; } @Override public String toString() { return "compatibility"; } } ././@LongLink0100644 0000000 0000000 00000000157 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BrowserCompatSpecFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BrowserCompatSpecFa0100644 0000000 0000000 00000006171 12301751705 032426 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Collection; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.CookieSpecFactory; import org.apache.http.cookie.CookieSpecProvider; import org.apache.http.cookie.params.CookieSpecPNames; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; /** * {@link CookieSpecProvider} implementation that creates and initializes * {@link BrowserCompatSpec} instances. * * @since 4.0 */ @Immutable @SuppressWarnings("deprecation") public class BrowserCompatSpecFactory implements CookieSpecFactory, CookieSpecProvider { public enum SecurityLevel { SECURITYLEVEL_DEFAULT, SECURITYLEVEL_IE_MEDIUM } private final String[] datepatterns; private final SecurityLevel securityLevel; public BrowserCompatSpecFactory(final String[] datepatterns, final SecurityLevel securityLevel) { super(); this.datepatterns = datepatterns; this.securityLevel = securityLevel; } public BrowserCompatSpecFactory(final String[] datepatterns) { this(null, SecurityLevel.SECURITYLEVEL_DEFAULT); } public BrowserCompatSpecFactory() { this(null, SecurityLevel.SECURITYLEVEL_DEFAULT); } public CookieSpec newInstance(final HttpParams params) { if (params != null) { String[] patterns = null; final Collection param = (Collection) params.getParameter( CookieSpecPNames.DATE_PATTERNS); if (param != null) { patterns = new String[param.size()]; patterns = param.toArray(patterns); } return new BrowserCompatSpec(patterns, securityLevel); } else { return new BrowserCompatSpec(null, securityLevel); } } public CookieSpec create(final HttpContext context) { return new BrowserCompatSpec(this.datepatterns); } } ././@LongLink0100644 0000000 0000000 00000000173 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BrowserCompatVersionAttributeHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/BrowserCompatVersio0100644 0000000 0000000 00000004322 12301751705 032530 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; /** * "Version" cookie attribute handler for BrowserCompat cookie spec. * * @since 4.3 */ @Immutable public class BrowserCompatVersionAttributeHandler extends AbstractCookieAttributeHandler { public BrowserCompatVersionAttributeHandler() { super(); } /** * Parse cookie version attribute. */ public void parse(final SetCookie cookie, final String value) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); if (value == null) { throw new MalformedCookieException("Missing value for version attribute"); } int version = 0; try { version = Integer.parseInt(value); } catch (final NumberFormatException e) { // Just ignore invalid versions } cookie.setVersion(version); } } ././@LongLink0100644 0000000 0000000 00000000145 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/CookieSpecBase.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/CookieSpecBase.java0100644 0000000 0000000 00000010704 12301751705 032311 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.ArrayList; import java.util.List; import java.util.Locale; import org.apache.http.HeaderElement; import org.apache.http.NameValuePair; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.util.Args; /** * Cookie management functions shared by all specification. * * * @since 4.0 */ @NotThreadSafe // AbstractCookieSpec is not thread-safe public abstract class CookieSpecBase extends AbstractCookieSpec { protected static String getDefaultPath(final CookieOrigin origin) { String defaultPath = origin.getPath(); int lastSlashIndex = defaultPath.lastIndexOf('/'); if (lastSlashIndex >= 0) { if (lastSlashIndex == 0) { //Do not remove the very first slash lastSlashIndex = 1; } defaultPath = defaultPath.substring(0, lastSlashIndex); } return defaultPath; } protected static String getDefaultDomain(final CookieOrigin origin) { return origin.getHost(); } protected List parse(final HeaderElement[] elems, final CookieOrigin origin) throws MalformedCookieException { final List cookies = new ArrayList(elems.length); for (final HeaderElement headerelement : elems) { final String name = headerelement.getName(); final String value = headerelement.getValue(); if (name == null || name.length() == 0) { throw new MalformedCookieException("Cookie name may not be empty"); } final BasicClientCookie cookie = new BasicClientCookie(name, value); cookie.setPath(getDefaultPath(origin)); cookie.setDomain(getDefaultDomain(origin)); // cycle through the parameters final NameValuePair[] attribs = headerelement.getParameters(); for (int j = attribs.length - 1; j >= 0; j--) { final NameValuePair attrib = attribs[j]; final String s = attrib.getName().toLowerCase(Locale.ENGLISH); cookie.setAttribute(s, attrib.getValue()); final CookieAttributeHandler handler = findAttribHandler(s); if (handler != null) { handler.parse(cookie, attrib.getValue()); } } cookies.add(cookie); } return cookies; } public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); for (final CookieAttributeHandler handler: getAttribHandlers()) { handler.validate(cookie, origin); } } public boolean match(final Cookie cookie, final CookieOrigin origin) { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); for (final CookieAttributeHandler handler: getAttribHandlers()) { if (!handler.match(cookie, origin)) { return false; } } return true; } } ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/DateParseException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/DateParseException.0100644 0000000 0000000 00000003316 12301751705 032360 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; /** * An exception to indicate an error parsing a date string. * * @see DateUtils * * * @since 4.0 */ @Immutable public class DateParseException extends Exception { private static final long serialVersionUID = 4417696455000643370L; /** * */ public DateParseException() { super(); } /** * @param message the exception message */ public DateParseException(final String message) { super(message); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/IgnoreSpec.java0100644 0000000 0000000 00000004022 12301751705 031524 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Collections; import java.util.List; import org.apache.http.Header; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; /** * CookieSpec that ignores all cookies * * @since 4.1 */ @NotThreadSafe // superclass is @NotThreadSafe public class IgnoreSpec extends CookieSpecBase { public int getVersion() { return 0; } public List parse(final Header header, final CookieOrigin origin) throws MalformedCookieException { return Collections.emptyList(); } public List
formatCookies(final List cookies) { return Collections.emptyList(); } public Header getVersionHeader() { return null; } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/IgnoreSpecFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/IgnoreSpecFactory.j0100644 0000000 0000000 00000003672 12301751705 032376 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.CookieSpecFactory; import org.apache.http.cookie.CookieSpecProvider; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; /** * {@link CookieSpecProvider} implementation that ignores all cookies. * * @since 4.1 */ @Immutable @SuppressWarnings("deprecation") public class IgnoreSpecFactory implements CookieSpecFactory, CookieSpecProvider { public IgnoreSpecFactory() { super(); } public CookieSpec newInstance(final HttpParams params) { return new IgnoreSpec(); } public CookieSpec create(final HttpContext context) { return new IgnoreSpec(); } } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDomainHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDomainHandl0100644 0000000 0000000 00000007453 12301751705 032422 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Locale; import java.util.StringTokenizer; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.util.Args; /** * * @since 4.0 */ @Immutable public class NetscapeDomainHandler extends BasicDomainHandler { public NetscapeDomainHandler() { super(); } @Override public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { super.validate(cookie, origin); // Perform Netscape Cookie draft specific validation final String host = origin.getHost(); final String domain = cookie.getDomain(); if (host.contains(".")) { final int domainParts = new StringTokenizer(domain, ".").countTokens(); if (isSpecialDomain(domain)) { if (domainParts < 2) { throw new CookieRestrictionViolationException("Domain attribute \"" + domain + "\" violates the Netscape cookie specification for " + "special domains"); } } else { if (domainParts < 3) { throw new CookieRestrictionViolationException("Domain attribute \"" + domain + "\" violates the Netscape cookie specification"); } } } } /** * Checks if the given domain is in one of the seven special * top level domains defined by the Netscape cookie specification. * @param domain The domain. * @return True if the specified domain is "special" */ private static boolean isSpecialDomain(final String domain) { final String ucDomain = domain.toUpperCase(Locale.ENGLISH); return ucDomain.endsWith(".COM") || ucDomain.endsWith(".EDU") || ucDomain.endsWith(".NET") || ucDomain.endsWith(".GOV") || ucDomain.endsWith(".MIL") || ucDomain.endsWith(".ORG") || ucDomain.endsWith(".INT"); } @Override public boolean match(final Cookie cookie, final CookieOrigin origin) { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); final String host = origin.getHost(); final String domain = cookie.getDomain(); if (domain == null) { return false; } return host.endsWith(domain); } } ././@LongLink0100644 0000000 0000000 00000000160 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDraftHeaderParser.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDraftHeader0100644 0000000 0000000 00000010431 12301751705 032403 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.ArrayList; import java.util.List; import org.apache.http.HeaderElement; import org.apache.http.NameValuePair; import org.apache.http.ParseException; import org.apache.http.annotation.Immutable; import org.apache.http.message.BasicHeaderElement; import org.apache.http.message.BasicNameValuePair; import org.apache.http.message.ParserCursor; import org.apache.http.protocol.HTTP; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; /** * * @since 4.0 */ @Immutable public class NetscapeDraftHeaderParser { public final static NetscapeDraftHeaderParser DEFAULT = new NetscapeDraftHeaderParser(); public NetscapeDraftHeaderParser() { super(); } public HeaderElement parseHeader( final CharArrayBuffer buffer, final ParserCursor cursor) throws ParseException { Args.notNull(buffer, "Char array buffer"); Args.notNull(cursor, "Parser cursor"); final NameValuePair nvp = parseNameValuePair(buffer, cursor); final List params = new ArrayList(); while (!cursor.atEnd()) { final NameValuePair param = parseNameValuePair(buffer, cursor); params.add(param); } return new BasicHeaderElement( nvp.getName(), nvp.getValue(), params.toArray(new NameValuePair[params.size()])); } private NameValuePair parseNameValuePair( final CharArrayBuffer buffer, final ParserCursor cursor) { boolean terminated = false; int pos = cursor.getPos(); final int indexFrom = cursor.getPos(); final int indexTo = cursor.getUpperBound(); // Find name String name = null; while (pos < indexTo) { final char ch = buffer.charAt(pos); if (ch == '=') { break; } if (ch == ';') { terminated = true; break; } pos++; } if (pos == indexTo) { terminated = true; name = buffer.substringTrimmed(indexFrom, indexTo); } else { name = buffer.substringTrimmed(indexFrom, pos); pos++; } if (terminated) { cursor.updatePos(pos); return new BasicNameValuePair(name, null); } // Find value String value = null; int i1 = pos; while (pos < indexTo) { final char ch = buffer.charAt(pos); if (ch == ';') { terminated = true; break; } pos++; } int i2 = pos; // Trim leading white spaces while (i1 < i2 && (HTTP.isWhitespace(buffer.charAt(i1)))) { i1++; } // Trim trailing white spaces while ((i2 > i1) && (HTTP.isWhitespace(buffer.charAt(i2 - 1)))) { i2--; } value = buffer.substring(i1, i2); if (terminated) { pos++; } cursor.updatePos(pos); return new BasicNameValuePair(name, value); } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDraftSpec.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDraftSpec.j0100644 0000000 0000000 00000014713 12301751705 032344 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.ArrayList; import java.util.List; import org.apache.http.FormattedHeader; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SM; import org.apache.http.message.BufferedHeader; import org.apache.http.message.ParserCursor; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; /** * This {@link org.apache.http.cookie.CookieSpec} implementation conforms to * the original draft specification published by Netscape Communications. * It should be avoided unless absolutely necessary for compatibility with * legacy applications. * * @since 4.0 */ @NotThreadSafe // superclass is @NotThreadSafe public class NetscapeDraftSpec extends CookieSpecBase { protected static final String EXPIRES_PATTERN = "EEE, dd-MMM-yy HH:mm:ss z"; private final String[] datepatterns; /** Default constructor */ public NetscapeDraftSpec(final String[] datepatterns) { super(); if (datepatterns != null) { this.datepatterns = datepatterns.clone(); } else { this.datepatterns = new String[] { EXPIRES_PATTERN }; } registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler()); registerAttribHandler(ClientCookie.DOMAIN_ATTR, new NetscapeDomainHandler()); registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler()); registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler()); registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler()); registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler( this.datepatterns)); } /** Default constructor */ public NetscapeDraftSpec() { this(null); } /** * Parses the Set-Cookie value into an array of Cookies. * *

Syntax of the Set-Cookie HTTP Response Header:

* *

This is the format a CGI script would use to add to * the HTTP headers a new piece of data which is to be stored by * the client for later retrieval.

* *
      *  Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure
      * 
* *

Please note that the Netscape draft specification does not fully conform to the HTTP * header format. Comma character if present in Set-Cookie will not be treated * as a header element separator

* * @see * The Cookie Spec. * * @param header the Set-Cookie received from the server * @return an array of Cookies parsed from the Set-Cookie value * @throws MalformedCookieException if an exception occurs during parsing */ public List parse(final Header header, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(header, "Header"); Args.notNull(origin, "Cookie origin"); if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE)) { throw new MalformedCookieException("Unrecognized cookie header '" + header.toString() + "'"); } final NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT; final CharArrayBuffer buffer; final ParserCursor cursor; if (header instanceof FormattedHeader) { buffer = ((FormattedHeader) header).getBuffer(); cursor = new ParserCursor( ((FormattedHeader) header).getValuePos(), buffer.length()); } else { final String s = header.getValue(); if (s == null) { throw new MalformedCookieException("Header value is null"); } buffer = new CharArrayBuffer(s.length()); buffer.append(s); cursor = new ParserCursor(0, buffer.length()); } return parse(new HeaderElement[] { parser.parseHeader(buffer, cursor) }, origin); } public List
formatCookies(final List cookies) { Args.notEmpty(cookies, "List of cookies"); final CharArrayBuffer buffer = new CharArrayBuffer(20 * cookies.size()); buffer.append(SM.COOKIE); buffer.append(": "); for (int i = 0; i < cookies.size(); i++) { final Cookie cookie = cookies.get(i); if (i > 0) { buffer.append("; "); } buffer.append(cookie.getName()); final String s = cookie.getValue(); if (s != null) { buffer.append("="); buffer.append(s); } } final List
headers = new ArrayList
(1); headers.add(new BufferedHeader(buffer)); return headers; } public int getVersion() { return 0; } public Header getVersionHeader() { return null; } @Override public String toString() { return "netscape"; } } ././@LongLink0100644 0000000 0000000 00000000157 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDraftSpecFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/NetscapeDraftSpecFa0100644 0000000 0000000 00000005313 12301751705 032357 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Collection; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.CookieSpecFactory; import org.apache.http.cookie.CookieSpecProvider; import org.apache.http.cookie.params.CookieSpecPNames; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; /** * {@link CookieSpecProvider} implementation that creates and initializes * {@link NetscapeDraftSpec} instances. * * @since 4.0 */ @Immutable @SuppressWarnings("deprecation") public class NetscapeDraftSpecFactory implements CookieSpecFactory, CookieSpecProvider { private final String[] datepatterns; public NetscapeDraftSpecFactory(final String[] datepatterns) { super(); this.datepatterns = datepatterns; } public NetscapeDraftSpecFactory() { this(null); } public CookieSpec newInstance(final HttpParams params) { if (params != null) { String[] patterns = null; final Collection param = (Collection) params.getParameter( CookieSpecPNames.DATE_PATTERNS); if (param != null) { patterns = new String[param.size()]; patterns = param.toArray(patterns); } return new NetscapeDraftSpec(patterns); } else { return new NetscapeDraftSpec(); } } public CookieSpec create(final HttpContext context) { return new NetscapeDraftSpec(this.datepatterns); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/package-info.java0100644 0000000 0000000 00000002443 12301751705 032017 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Default implementations of standard and common HTTP state * management policies. */ package org.apache.http.impl.cookie; ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/PublicSuffixFilter.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/PublicSuffixFilter.0100644 0000000 0000000 00000010603 12301751705 032377 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Collection; import java.util.HashSet; import java.util.Set; import org.apache.http.client.utils.Punycode; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; /** * Wraps a CookieAttributeHandler and leverages its match method * to never match a suffix from a black list. May be used to provide * additional security for cross-site attack types by preventing * cookies from apparent domains that are not publicly available. * An uptodate list of suffixes can be obtained from * publicsuffix.org * * @since 4.0 */ public class PublicSuffixFilter implements CookieAttributeHandler { private final CookieAttributeHandler wrapped; private Set exceptions; private Set suffixes; public PublicSuffixFilter(final CookieAttributeHandler wrapped) { this.wrapped = wrapped; } /** * Sets the suffix blacklist patterns. * A pattern can be "com", "*.jp" * TODO add support for patterns like "lib.*.us" * @param suffixes */ public void setPublicSuffixes(final Collection suffixes) { this.suffixes = new HashSet(suffixes); } /** * Sets the exceptions from the blacklist. Exceptions can not be patterns. * TODO add support for patterns * @param exceptions */ public void setExceptions(final Collection exceptions) { this.exceptions = new HashSet(exceptions); } /** * Never matches if the cookie's domain is from the blacklist. */ public boolean match(final Cookie cookie, final CookieOrigin origin) { if (isForPublicSuffix(cookie)) { return false; } return wrapped.match(cookie, origin); } public void parse(final SetCookie cookie, final String value) throws MalformedCookieException { wrapped.parse(cookie, value); } public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { wrapped.validate(cookie, origin); } private boolean isForPublicSuffix(final Cookie cookie) { String domain = cookie.getDomain(); if (domain.startsWith(".")) { domain = domain.substring(1); } domain = Punycode.toUnicode(domain); // An exception rule takes priority over any other matching rule. if (this.exceptions != null) { if (this.exceptions.contains(domain)) { return false; } } if (this.suffixes == null) { return false; } do { if (this.suffixes.contains(domain)) { return true; } // patterns if (domain.startsWith("*.")) { domain = domain.substring(2); } final int nextdot = domain.indexOf('.'); if (nextdot == -1) { break; } domain = "*" + domain.substring(nextdot); } while (domain.length() > 0); return false; } } ././@LongLink0100644 0000000 0000000 00000000155 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/PublicSuffixListParser.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/PublicSuffixListPar0100644 0000000 0000000 00000010351 12301751705 032452 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.Collection; import org.apache.http.annotation.Immutable; /** * Parses the list from publicsuffix.org * and configures a PublicSuffixFilter. * * @since 4.0 */ @Immutable public class PublicSuffixListParser { private static final int MAX_LINE_LEN = 256; private final PublicSuffixFilter filter; PublicSuffixListParser(final PublicSuffixFilter filter) { this.filter = filter; } /** * Parses the public suffix list format. * When creating the reader from the file, make sure to * use the correct encoding (the original list is in UTF-8). * * @param list the suffix list. The caller is responsible for closing the reader. * @throws IOException on error while reading from list */ public void parse(final Reader list) throws IOException { final Collection rules = new ArrayList(); final Collection exceptions = new ArrayList(); final BufferedReader r = new BufferedReader(list); final StringBuilder sb = new StringBuilder(256); boolean more = true; while (more) { more = readLine(r, sb); String line = sb.toString(); if (line.length() == 0) { continue; } if (line.startsWith("//")) { continue; //entire lines can also be commented using // } if (line.startsWith(".")) { line = line.substring(1); // A leading dot is optional } // An exclamation mark (!) at the start of a rule marks an exception to a previous wildcard rule final boolean isException = line.startsWith("!"); if (isException) { line = line.substring(1); } if (isException) { exceptions.add(line); } else { rules.add(line); } } filter.setPublicSuffixes(rules); filter.setExceptions(exceptions); } /** * * @param r * @param sb * @return false when the end of the stream is reached * @throws IOException */ private boolean readLine(final Reader r, final StringBuilder sb) throws IOException { sb.setLength(0); int b; boolean hitWhitespace = false; while ((b = r.read()) != -1) { final char c = (char) b; if (c == '\n') { break; } // Each line is only read up to the first whitespace if (Character.isWhitespace(c)) { hitWhitespace = true; } if (!hitWhitespace) { sb.append(c); } if (sb.length() > MAX_LINE_LEN) { throw new IOException("Line too long"); // prevent excess memory usage } } return (b != -1); } } ././@LongLink0100644 0000000 0000000 00000000153 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109DomainHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109DomainHandle0100644 0000000 0000000 00000011373 12301751705 031747 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Locale; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; /** * * @since 4.0 */ @Immutable public class RFC2109DomainHandler implements CookieAttributeHandler { public RFC2109DomainHandler() { super(); } public void parse(final SetCookie cookie, final String value) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); if (value == null) { throw new MalformedCookieException("Missing value for domain attribute"); } if (value.trim().length() == 0) { throw new MalformedCookieException("Blank value for domain attribute"); } cookie.setDomain(value); } public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); String host = origin.getHost(); final String domain = cookie.getDomain(); if (domain == null) { throw new CookieRestrictionViolationException("Cookie domain may not be null"); } if (!domain.equals(host)) { int dotIndex = domain.indexOf('.'); if (dotIndex == -1) { throw new CookieRestrictionViolationException("Domain attribute \"" + domain + "\" does not match the host \"" + host + "\""); } // domain must start with dot if (!domain.startsWith(".")) { throw new CookieRestrictionViolationException("Domain attribute \"" + domain + "\" violates RFC 2109: domain must start with a dot"); } // domain must have at least one embedded dot dotIndex = domain.indexOf('.', 1); if (dotIndex < 0 || dotIndex == domain.length() - 1) { throw new CookieRestrictionViolationException("Domain attribute \"" + domain + "\" violates RFC 2109: domain must contain an embedded dot"); } host = host.toLowerCase(Locale.ENGLISH); if (!host.endsWith(domain)) { throw new CookieRestrictionViolationException( "Illegal domain attribute \"" + domain + "\". Domain of origin: \"" + host + "\""); } // host minus domain may not contain any dots final String hostWithoutDomain = host.substring(0, host.length() - domain.length()); if (hostWithoutDomain.indexOf('.') != -1) { throw new CookieRestrictionViolationException("Domain attribute \"" + domain + "\" violates RFC 2109: host minus domain may not contain any dots"); } } } public boolean match(final Cookie cookie, final CookieOrigin origin) { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); final String host = origin.getHost(); final String domain = cookie.getDomain(); if (domain == null) { return false; } return host.equals(domain) || (domain.startsWith(".") && host.endsWith(domain)); } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109Spec.java0100644 0000000 0000000 00000021507 12301751705 031236 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.client.utils.DateUtils; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookiePathComparator; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SM; import org.apache.http.message.BufferedHeader; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; /** * RFC 2109 compliant {@link org.apache.http.cookie.CookieSpec} implementation. * This is an older version of the official HTTP state management specification * superseded by RFC 2965. * * @see RFC2965Spec * * @since 4.0 */ @NotThreadSafe // superclass is @NotThreadSafe public class RFC2109Spec extends CookieSpecBase { private final static CookiePathComparator PATH_COMPARATOR = new CookiePathComparator(); private final static String[] DATE_PATTERNS = { DateUtils.PATTERN_RFC1123, DateUtils.PATTERN_RFC1036, DateUtils.PATTERN_ASCTIME }; private final String[] datepatterns; private final boolean oneHeader; /** Default constructor */ public RFC2109Spec(final String[] datepatterns, final boolean oneHeader) { super(); if (datepatterns != null) { this.datepatterns = datepatterns.clone(); } else { this.datepatterns = DATE_PATTERNS; } this.oneHeader = oneHeader; registerAttribHandler(ClientCookie.VERSION_ATTR, new RFC2109VersionHandler()); registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler()); registerAttribHandler(ClientCookie.DOMAIN_ATTR, new RFC2109DomainHandler()); registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler()); registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler()); registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler()); registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler( this.datepatterns)); } /** Default constructor */ public RFC2109Spec() { this(null, false); } public List parse(final Header header, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(header, "Header"); Args.notNull(origin, "Cookie origin"); if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE)) { throw new MalformedCookieException("Unrecognized cookie header '" + header.toString() + "'"); } final HeaderElement[] elems = header.getElements(); return parse(elems, origin); } @Override public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); final String name = cookie.getName(); if (name.indexOf(' ') != -1) { throw new CookieRestrictionViolationException("Cookie name may not contain blanks"); } if (name.startsWith("$")) { throw new CookieRestrictionViolationException("Cookie name may not start with $"); } super.validate(cookie, origin); } public List
formatCookies(final List cookies) { Args.notEmpty(cookies, "List of cookies"); List cookieList; if (cookies.size() > 1) { // Create a mutable copy and sort the copy. cookieList = new ArrayList(cookies); Collections.sort(cookieList, PATH_COMPARATOR); } else { cookieList = cookies; } if (this.oneHeader) { return doFormatOneHeader(cookieList); } else { return doFormatManyHeaders(cookieList); } } private List
doFormatOneHeader(final List cookies) { int version = Integer.MAX_VALUE; // Pick the lowest common denominator for (final Cookie cookie : cookies) { if (cookie.getVersion() < version) { version = cookie.getVersion(); } } final CharArrayBuffer buffer = new CharArrayBuffer(40 * cookies.size()); buffer.append(SM.COOKIE); buffer.append(": "); buffer.append("$Version="); buffer.append(Integer.toString(version)); for (final Cookie cooky : cookies) { buffer.append("; "); final Cookie cookie = cooky; formatCookieAsVer(buffer, cookie, version); } final List
headers = new ArrayList
(1); headers.add(new BufferedHeader(buffer)); return headers; } private List
doFormatManyHeaders(final List cookies) { final List
headers = new ArrayList
(cookies.size()); for (final Cookie cookie : cookies) { final int version = cookie.getVersion(); final CharArrayBuffer buffer = new CharArrayBuffer(40); buffer.append("Cookie: "); buffer.append("$Version="); buffer.append(Integer.toString(version)); buffer.append("; "); formatCookieAsVer(buffer, cookie, version); headers.add(new BufferedHeader(buffer)); } return headers; } /** * Return a name/value string suitable for sending in a "Cookie" * header as defined in RFC 2109 for backward compatibility with cookie * version 0 * @param buffer The char array buffer to use for output * @param name The cookie name * @param value The cookie value * @param version The cookie version */ protected void formatParamAsVer(final CharArrayBuffer buffer, final String name, final String value, final int version) { buffer.append(name); buffer.append("="); if (value != null) { if (version > 0) { buffer.append('\"'); buffer.append(value); buffer.append('\"'); } else { buffer.append(value); } } } /** * Return a string suitable for sending in a "Cookie" header * as defined in RFC 2109 for backward compatibility with cookie version 0 * @param buffer The char array buffer to use for output * @param cookie The {@link Cookie} to be formatted as string * @param version The version to use. */ protected void formatCookieAsVer(final CharArrayBuffer buffer, final Cookie cookie, final int version) { formatParamAsVer(buffer, cookie.getName(), cookie.getValue(), version); if (cookie.getPath() != null) { if (cookie instanceof ClientCookie && ((ClientCookie) cookie).containsAttribute(ClientCookie.PATH_ATTR)) { buffer.append("; "); formatParamAsVer(buffer, "$Path", cookie.getPath(), version); } } if (cookie.getDomain() != null) { if (cookie instanceof ClientCookie && ((ClientCookie) cookie).containsAttribute(ClientCookie.DOMAIN_ATTR)) { buffer.append("; "); formatParamAsVer(buffer, "$Domain", cookie.getDomain(), version); } } } public int getVersion() { return 1; } public Header getVersionHeader() { return null; } @Override public String toString() { return "rfc2109"; } } ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109SpecFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109SpecFactory.0100644 0000000 0000000 00000005661 12301751705 031727 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Collection; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.CookieSpecFactory; import org.apache.http.cookie.CookieSpecProvider; import org.apache.http.cookie.params.CookieSpecPNames; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; /** * {@link CookieSpecProvider} implementation that creates and initializes * {@link RFC2109Spec} instances. * * @since 4.0 */ @Immutable @SuppressWarnings("deprecation") public class RFC2109SpecFactory implements CookieSpecFactory, CookieSpecProvider { private final String[] datepatterns; private final boolean oneHeader; public RFC2109SpecFactory(final String[] datepatterns, final boolean oneHeader) { super(); this.datepatterns = datepatterns; this.oneHeader = oneHeader; } public RFC2109SpecFactory() { this(null, false); } public CookieSpec newInstance(final HttpParams params) { if (params != null) { String[] patterns = null; final Collection param = (Collection) params.getParameter( CookieSpecPNames.DATE_PATTERNS); if (param != null) { patterns = new String[param.size()]; patterns = param.toArray(patterns); } final boolean singleHeader = params.getBooleanParameter( CookieSpecPNames.SINGLE_COOKIE_HEADER, false); return new RFC2109Spec(patterns, singleHeader); } else { return new RFC2109Spec(); } } public CookieSpec create(final HttpContext context) { return new RFC2109Spec(this.datepatterns, this.oneHeader); } } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109VersionHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2109VersionHandl0100644 0000000 0000000 00000005217 12301751705 032020 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; /** * * @since 4.0 */ @Immutable public class RFC2109VersionHandler extends AbstractCookieAttributeHandler { public RFC2109VersionHandler() { super(); } public void parse(final SetCookie cookie, final String value) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); if (value == null) { throw new MalformedCookieException("Missing value for version attribute"); } if (value.trim().length() == 0) { throw new MalformedCookieException("Blank value for version attribute"); } try { cookie.setVersion(Integer.parseInt(value)); } catch (final NumberFormatException e) { throw new MalformedCookieException("Invalid version: " + e.getMessage()); } } @Override public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); if (cookie.getVersion() < 0) { throw new CookieRestrictionViolationException("Cookie version may not be negative"); } } } ././@LongLink0100644 0000000 0000000 00000000170 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965CommentUrlAttributeHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965CommentUrlAt0100644 0000000 0000000 00000004473 12301751705 032013 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.cookie.SetCookie2; /** * "CommentURL" cookie attribute handler for RFC 2965 cookie spec. * * @since 4.0 */ @Immutable public class RFC2965CommentUrlAttributeHandler implements CookieAttributeHandler { public RFC2965CommentUrlAttributeHandler() { super(); } public void parse(final SetCookie cookie, final String commenturl) throws MalformedCookieException { if (cookie instanceof SetCookie2) { final SetCookie2 cookie2 = (SetCookie2) cookie; cookie2.setCommentURL(commenturl); } } public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { } public boolean match(final Cookie cookie, final CookieOrigin origin) { return true; } } ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965DiscardAttributeHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965DiscardAttri0100644 0000000 0000000 00000004451 12301751705 032012 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.cookie.SetCookie2; /** * "Discard" cookie attribute handler for RFC 2965 cookie spec. * * @since 4.0 */ @Immutable public class RFC2965DiscardAttributeHandler implements CookieAttributeHandler { public RFC2965DiscardAttributeHandler() { super(); } public void parse(final SetCookie cookie, final String commenturl) throws MalformedCookieException { if (cookie instanceof SetCookie2) { final SetCookie2 cookie2 = (SetCookie2) cookie; cookie2.setDiscard(true); } } public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { } public boolean match(final Cookie cookie, final CookieOrigin origin) { return true; } } ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965DomainAttributeHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965DomainAttrib0100644 0000000 0000000 00000017206 12301751705 032014 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Locale; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.util.Args; /** * "Domain" cookie attribute handler for RFC 2965 cookie spec. * * * @since 3.1 */ @Immutable public class RFC2965DomainAttributeHandler implements CookieAttributeHandler { public RFC2965DomainAttributeHandler() { super(); } /** * Parse cookie domain attribute. */ public void parse( final SetCookie cookie, final String domain) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); if (domain == null) { throw new MalformedCookieException( "Missing value for domain attribute"); } if (domain.trim().length() == 0) { throw new MalformedCookieException( "Blank value for domain attribute"); } String s = domain; s = s.toLowerCase(Locale.ENGLISH); if (!domain.startsWith(".")) { // Per RFC 2965 section 3.2.2 // "... If an explicitly specified value does not start with // a dot, the user agent supplies a leading dot ..." // That effectively implies that the domain attribute // MAY NOT be an IP address of a host name s = '.' + s; } cookie.setDomain(s); } /** * Performs domain-match as defined by the RFC2965. *

* Host A's name domain-matches host B's if *

    *
      their host name strings string-compare equal; or
    *
      A is a HDN string and has the form NB, where N is a non-empty * name string, B has the form .B', and B' is a HDN string. (So, * x.y.com domain-matches .Y.com but not Y.com.)
    *
* * @param host host name where cookie is received from or being sent to. * @param domain The cookie domain attribute. * @return true if the specified host matches the given domain. */ public boolean domainMatch(final String host, final String domain) { final boolean match = host.equals(domain) || (domain.startsWith(".") && host.endsWith(domain)); return match; } /** * Validate cookie domain attribute. */ public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); final String host = origin.getHost().toLowerCase(Locale.ENGLISH); if (cookie.getDomain() == null) { throw new CookieRestrictionViolationException("Invalid cookie state: " + "domain not specified"); } final String cookieDomain = cookie.getDomain().toLowerCase(Locale.ENGLISH); if (cookie instanceof ClientCookie && ((ClientCookie) cookie).containsAttribute(ClientCookie.DOMAIN_ATTR)) { // Domain attribute must start with a dot if (!cookieDomain.startsWith(".")) { throw new CookieRestrictionViolationException("Domain attribute \"" + cookie.getDomain() + "\" violates RFC 2109: domain must start with a dot"); } // Domain attribute must contain at least one embedded dot, // or the value must be equal to .local. final int dotIndex = cookieDomain.indexOf('.', 1); if (((dotIndex < 0) || (dotIndex == cookieDomain.length() - 1)) && (!cookieDomain.equals(".local"))) { throw new CookieRestrictionViolationException( "Domain attribute \"" + cookie.getDomain() + "\" violates RFC 2965: the value contains no embedded dots " + "and the value is not .local"); } // The effective host name must domain-match domain attribute. if (!domainMatch(host, cookieDomain)) { throw new CookieRestrictionViolationException( "Domain attribute \"" + cookie.getDomain() + "\" violates RFC 2965: effective host name does not " + "domain-match domain attribute."); } // effective host name minus domain must not contain any dots final String effectiveHostWithoutDomain = host.substring( 0, host.length() - cookieDomain.length()); if (effectiveHostWithoutDomain.indexOf('.') != -1) { throw new CookieRestrictionViolationException("Domain attribute \"" + cookie.getDomain() + "\" violates RFC 2965: " + "effective host minus domain may not contain any dots"); } } else { // Domain was not specified in header. In this case, domain must // string match request host (case-insensitive). if (!cookie.getDomain().equals(host)) { throw new CookieRestrictionViolationException("Illegal domain attribute: \"" + cookie.getDomain() + "\"." + "Domain of origin: \"" + host + "\""); } } } /** * Match cookie domain attribute. */ public boolean match(final Cookie cookie, final CookieOrigin origin) { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); final String host = origin.getHost().toLowerCase(Locale.ENGLISH); final String cookieDomain = cookie.getDomain(); // The effective host name MUST domain-match the Domain // attribute of the cookie. if (!domainMatch(host, cookieDomain)) { return false; } // effective host name minus domain must not contain any dots final String effectiveHostWithoutDomain = host.substring( 0, host.length() - cookieDomain.length()); return effectiveHostWithoutDomain.indexOf('.') == -1; } } ././@LongLink0100644 0000000 0000000 00000000162 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965PortAttributeHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965PortAttribut0100644 0000000 0000000 00000013443 12301751705 032101 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.StringTokenizer; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.cookie.SetCookie2; import org.apache.http.util.Args; /** * "Port" cookie attribute handler for RFC 2965 cookie spec. * * @since 4.0 */ @Immutable public class RFC2965PortAttributeHandler implements CookieAttributeHandler { public RFC2965PortAttributeHandler() { super(); } /** * Parses the given Port attribute value (e.g. "8000,8001,8002") * into an array of ports. * * @param portValue port attribute value * @return parsed array of ports * @throws MalformedCookieException if there is a problem in * parsing due to invalid portValue. */ private static int[] parsePortAttribute(final String portValue) throws MalformedCookieException { final StringTokenizer st = new StringTokenizer(portValue, ","); final int[] ports = new int[st.countTokens()]; try { int i = 0; while(st.hasMoreTokens()) { ports[i] = Integer.parseInt(st.nextToken().trim()); if (ports[i] < 0) { throw new MalformedCookieException ("Invalid Port attribute."); } ++i; } } catch (final NumberFormatException e) { throw new MalformedCookieException ("Invalid Port " + "attribute: " + e.getMessage()); } return ports; } /** * Returns true if the given port exists in the given * ports list. * * @param port port of host where cookie was received from or being sent to. * @param ports port list * @return true returns true if the given port exists in * the given ports list; false otherwise. */ private static boolean portMatch(final int port, final int[] ports) { boolean portInList = false; for (final int port2 : ports) { if (port == port2) { portInList = true; break; } } return portInList; } /** * Parse cookie port attribute. */ public void parse(final SetCookie cookie, final String portValue) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); if (cookie instanceof SetCookie2) { final SetCookie2 cookie2 = (SetCookie2) cookie; if (portValue != null && portValue.trim().length() > 0) { final int[] ports = parsePortAttribute(portValue); cookie2.setPorts(ports); } } } /** * Validate cookie port attribute. If the Port attribute was specified * in header, the request port must be in cookie's port list. */ public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); final int port = origin.getPort(); if (cookie instanceof ClientCookie && ((ClientCookie) cookie).containsAttribute(ClientCookie.PORT_ATTR)) { if (!portMatch(port, cookie.getPorts())) { throw new CookieRestrictionViolationException( "Port attribute violates RFC 2965: " + "Request port not found in cookie's port list."); } } } /** * Match cookie port attribute. If the Port attribute is not specified * in header, the cookie can be sent to any port. Otherwise, the request port * must be in the cookie's port list. */ public boolean match(final Cookie cookie, final CookieOrigin origin) { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); final int port = origin.getPort(); if (cookie instanceof ClientCookie && ((ClientCookie) cookie).containsAttribute(ClientCookie.PORT_ATTR)) { if (cookie.getPorts() == null) { // Invalid cookie state: port not specified return false; } if (!portMatch(port, cookie.getPorts())) { return false; } } return true; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965Spec.java0100644 0000000 0000000 00000021533 12301751705 031247 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.NameValuePair; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SM; import org.apache.http.message.BufferedHeader; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; /** * RFC 2965 compliant {@link org.apache.http.cookie.CookieSpec} implementation. * * @since 4.0 */ @NotThreadSafe // superclass is @NotThreadSafe public class RFC2965Spec extends RFC2109Spec { /** * Default constructor * */ public RFC2965Spec() { this(null, false); } public RFC2965Spec(final String[] datepatterns, final boolean oneHeader) { super(datepatterns, oneHeader); registerAttribHandler(ClientCookie.DOMAIN_ATTR, new RFC2965DomainAttributeHandler()); registerAttribHandler(ClientCookie.PORT_ATTR, new RFC2965PortAttributeHandler()); registerAttribHandler(ClientCookie.COMMENTURL_ATTR, new RFC2965CommentUrlAttributeHandler()); registerAttribHandler(ClientCookie.DISCARD_ATTR, new RFC2965DiscardAttributeHandler()); registerAttribHandler(ClientCookie.VERSION_ATTR, new RFC2965VersionAttributeHandler()); } @Override public List parse( final Header header, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(header, "Header"); Args.notNull(origin, "Cookie origin"); if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE2)) { throw new MalformedCookieException("Unrecognized cookie header '" + header.toString() + "'"); } final HeaderElement[] elems = header.getElements(); return createCookies(elems, adjustEffectiveHost(origin)); } @Override protected List parse( final HeaderElement[] elems, final CookieOrigin origin) throws MalformedCookieException { return createCookies(elems, adjustEffectiveHost(origin)); } private List createCookies( final HeaderElement[] elems, final CookieOrigin origin) throws MalformedCookieException { final List cookies = new ArrayList(elems.length); for (final HeaderElement headerelement : elems) { final String name = headerelement.getName(); final String value = headerelement.getValue(); if (name == null || name.length() == 0) { throw new MalformedCookieException("Cookie name may not be empty"); } final BasicClientCookie2 cookie = new BasicClientCookie2(name, value); cookie.setPath(getDefaultPath(origin)); cookie.setDomain(getDefaultDomain(origin)); cookie.setPorts(new int [] { origin.getPort() }); // cycle through the parameters final NameValuePair[] attribs = headerelement.getParameters(); // Eliminate duplicate attributes. The first occurrence takes precedence // See RFC2965: 3.2 Origin Server Role final Map attribmap = new HashMap(attribs.length); for (int j = attribs.length - 1; j >= 0; j--) { final NameValuePair param = attribs[j]; attribmap.put(param.getName().toLowerCase(Locale.ENGLISH), param); } for (final Map.Entry entry : attribmap.entrySet()) { final NameValuePair attrib = entry.getValue(); final String s = attrib.getName().toLowerCase(Locale.ENGLISH); cookie.setAttribute(s, attrib.getValue()); final CookieAttributeHandler handler = findAttribHandler(s); if (handler != null) { handler.parse(cookie, attrib.getValue()); } } cookies.add(cookie); } return cookies; } @Override public void validate( final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); super.validate(cookie, adjustEffectiveHost(origin)); } @Override public boolean match(final Cookie cookie, final CookieOrigin origin) { Args.notNull(cookie, "Cookie"); Args.notNull(origin, "Cookie origin"); return super.match(cookie, adjustEffectiveHost(origin)); } /** * Adds valid Port attribute value, e.g. "8000,8001,8002" */ @Override protected void formatCookieAsVer(final CharArrayBuffer buffer, final Cookie cookie, final int version) { super.formatCookieAsVer(buffer, cookie, version); // format port attribute if (cookie instanceof ClientCookie) { // Test if the port attribute as set by the origin server is not blank final String s = ((ClientCookie) cookie).getAttribute(ClientCookie.PORT_ATTR); if (s != null) { buffer.append("; $Port"); buffer.append("=\""); if (s.trim().length() > 0) { final int[] ports = cookie.getPorts(); if (ports != null) { final int len = ports.length; for (int i = 0; i < len; i++) { if (i > 0) { buffer.append(","); } buffer.append(Integer.toString(ports[i])); } } } buffer.append("\""); } } } /** * Set 'effective host name' as defined in RFC 2965. *

* If a host name contains no dots, the effective host name is * that name with the string .local appended to it. Otherwise * the effective host name is the same as the host name. Note * that all effective host names contain at least one dot. * * @param origin origin where cookie is received from or being sent to. */ private static CookieOrigin adjustEffectiveHost(final CookieOrigin origin) { String host = origin.getHost(); // Test if the host name appears to be a fully qualified DNS name, // IPv4 address or IPv6 address boolean isLocalHost = true; for (int i = 0; i < host.length(); i++) { final char ch = host.charAt(i); if (ch == '.' || ch == ':') { isLocalHost = false; break; } } if (isLocalHost) { host += ".local"; return new CookieOrigin( host, origin.getPort(), origin.getPath(), origin.isSecure()); } else { return origin; } } @Override public int getVersion() { return 1; } @Override public Header getVersionHeader() { final CharArrayBuffer buffer = new CharArrayBuffer(40); buffer.append(SM.COOKIE2); buffer.append(": "); buffer.append("$Version="); buffer.append(Integer.toString(getVersion())); return new BufferedHeader(buffer); } @Override public String toString() { return "rfc2965"; } } ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965SpecFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965SpecFactory.0100644 0000000 0000000 00000005661 12301751705 031741 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Collection; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.CookieSpecFactory; import org.apache.http.cookie.CookieSpecProvider; import org.apache.http.cookie.params.CookieSpecPNames; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; /** * {@link CookieSpecProvider} implementation that creates and initializes * {@link RFC2965Spec} instances. * * @since 4.0 */ @Immutable @SuppressWarnings("deprecation") public class RFC2965SpecFactory implements CookieSpecFactory, CookieSpecProvider { private final String[] datepatterns; private final boolean oneHeader; public RFC2965SpecFactory(final String[] datepatterns, final boolean oneHeader) { super(); this.datepatterns = datepatterns; this.oneHeader = oneHeader; } public RFC2965SpecFactory() { this(null, false); } public CookieSpec newInstance(final HttpParams params) { if (params != null) { String[] patterns = null; final Collection param = (Collection) params.getParameter( CookieSpecPNames.DATE_PATTERNS); if (param != null) { patterns = new String[param.size()]; patterns = param.toArray(patterns); } final boolean singleHeader = params.getBooleanParameter( CookieSpecPNames.SINGLE_COOKIE_HEADER, false); return new RFC2965Spec(patterns, singleHeader); } else { return new RFC2965Spec(); } } public CookieSpec create(final HttpContext context) { return new RFC2965Spec(this.datepatterns, this.oneHeader); } } ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965VersionAttributeHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/cookie/RFC2965VersionAttri0100644 0000000 0000000 00000006417 12301751705 032072 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.annotation.Immutable; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieRestrictionViolationException; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.apache.http.cookie.SetCookie2; import org.apache.http.util.Args; /** * "Version" cookie attribute handler for RFC 2965 cookie spec. * * @since 4.0 */ @Immutable public class RFC2965VersionAttributeHandler implements CookieAttributeHandler { public RFC2965VersionAttributeHandler() { super(); } /** * Parse cookie version attribute. */ public void parse(final SetCookie cookie, final String value) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); if (value == null) { throw new MalformedCookieException( "Missing value for version attribute"); } int version = -1; try { version = Integer.parseInt(value); } catch (final NumberFormatException e) { version = -1; } if (version < 0) { throw new MalformedCookieException("Invalid cookie version."); } cookie.setVersion(version); } /** * validate cookie version attribute. Version attribute is REQUIRED. */ public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { Args.notNull(cookie, "Cookie"); if (cookie instanceof SetCookie2) { if (cookie instanceof ClientCookie && !((ClientCookie) cookie).containsAttribute(ClientCookie.VERSION_ATTR)) { throw new CookieRestrictionViolationException( "Violates RFC 2965. Version attribute is required."); } } } public boolean match(final Cookie cookie, final CookieOrigin origin) { return true; } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/0040755 0000000 0000000 00000000000 12301751703 027304 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000155 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/BackoffStrategyExec.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/BackoffStrategyE0100644 0000000 0000000 00000007720 12301751703 032415 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.IOException; import java.lang.reflect.UndeclaredThrowableException; import org.apache.http.HttpException; import org.apache.http.annotation.Immutable; import org.apache.http.client.BackoffManager; import org.apache.http.client.ConnectionBackoffStrategy; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.util.Args; /** * @since 4.3 */ @Immutable public class BackoffStrategyExec implements ClientExecChain { private final ClientExecChain requestExecutor; private final ConnectionBackoffStrategy connectionBackoffStrategy; private final BackoffManager backoffManager; public BackoffStrategyExec( final ClientExecChain requestExecutor, final ConnectionBackoffStrategy connectionBackoffStrategy, final BackoffManager backoffManager) { super(); Args.notNull(requestExecutor, "HTTP client request executor"); Args.notNull(connectionBackoffStrategy, "Connection backoff strategy"); Args.notNull(backoffManager, "Backoff manager"); this.requestExecutor = requestExecutor; this.connectionBackoffStrategy = connectionBackoffStrategy; this.backoffManager = backoffManager; } public CloseableHttpResponse execute( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware) throws IOException, HttpException { Args.notNull(route, "HTTP route"); Args.notNull(request, "HTTP request"); Args.notNull(context, "HTTP context"); CloseableHttpResponse out = null; try { out = this.requestExecutor.execute(route, request, context, execAware); } catch (final Exception ex) { if (out != null) { out.close(); } if (this.connectionBackoffStrategy.shouldBackoff(ex)) { this.backoffManager.backOff(route); } if (ex instanceof RuntimeException) { throw (RuntimeException) ex; } if (ex instanceof HttpException) { throw (HttpException) ex; } if (ex instanceof IOException) { throw (IOException) ex; } throw new UndeclaredThrowableException(ex); } if (this.connectionBackoffStrategy.shouldBackoff(out)) { this.backoffManager.backOff(route); } else { this.backoffManager.probe(route); } return out; } } ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/ClientExecChain.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/ClientExecChain.0100644 0000000 0000000 00000006231 12301751703 032272 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.IOException; import org.apache.http.HttpException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; /** * This interface represents an element in the HTTP request execution chain. Each element can * either be a decorator around another element that implements a cross cutting aspect or * a self-contained executor capable of producing a response for the given request. *

* Important: please note it is required for decorators that implement post execution aspects * or response post-processing of any sort to release resources associated with the response * by calling {@link CloseableHttpResponse#close()} methods in case of an I/O, protocol or * runtime exception, or in case the response is not propagated to the caller. * * @since 4.3 */ public interface ClientExecChain { /** * Executes th request either by transmitting it to the target server or * by passing it onto the next executor in the request execution chain. * * @param route connection route. * @param request current request. * @param clientContext current HTTP context. * @param execAware receiver of notifications of blocking I/O operations. * @return HTTP response either received from the opposite endpoint * or generated locally. * @throws IOException in case of a I/O error. * (this type of exceptions are potentially recoverable). * @throws HttpException in case of an HTTP protocol error * (usually this type of exceptions are non-recoverable). */ CloseableHttpResponse execute( HttpRoute route, HttpRequestWrapper request, HttpClientContext clientContext, HttpExecutionAware execAware) throws IOException, HttpException; } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/ConnectionHolder.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/ConnectionHolder0100644 0000000 0000000 00000011237 12301751703 032465 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.Closeable; import java.io.IOException; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.http.HttpClientConnection; import org.apache.http.annotation.ThreadSafe; import org.apache.http.concurrent.Cancellable; import org.apache.http.conn.ConnectionReleaseTrigger; import org.apache.http.conn.HttpClientConnectionManager; /** * Internal connection holder. * * @since 4.3 */ @ThreadSafe class ConnectionHolder implements ConnectionReleaseTrigger, Cancellable, Closeable { private final Log log; private final HttpClientConnectionManager manager; private final HttpClientConnection managedConn; private volatile boolean reusable; private volatile Object state; private volatile long validDuration; private volatile TimeUnit tunit; private volatile boolean released; public ConnectionHolder( final Log log, final HttpClientConnectionManager manager, final HttpClientConnection managedConn) { super(); this.log = log; this.manager = manager; this.managedConn = managedConn; } public boolean isReusable() { return this.reusable; } public void markReusable() { this.reusable = true; } public void markNonReusable() { this.reusable = false; } public void setState(final Object state) { this.state = state; } public void setValidFor(final long duration, final TimeUnit tunit) { synchronized (this.managedConn) { this.validDuration = duration; this.tunit = tunit; } } public void releaseConnection() { synchronized (this.managedConn) { if (this.released) { return; } this.released = true; if (this.reusable) { this.manager.releaseConnection(this.managedConn, this.state, this.validDuration, this.tunit); } else { try { this.managedConn.close(); log.debug("Connection discarded"); } catch (final IOException ex) { if (this.log.isDebugEnabled()) { this.log.debug(ex.getMessage(), ex); } } finally { this.manager.releaseConnection( this.managedConn, null, 0, TimeUnit.MILLISECONDS); } } } } public void abortConnection() { synchronized (this.managedConn) { if (this.released) { return; } this.released = true; try { this.managedConn.shutdown(); log.debug("Connection discarded"); } catch (final IOException ex) { if (this.log.isDebugEnabled()) { this.log.debug(ex.getMessage(), ex); } } finally { this.manager.releaseConnection( this.managedConn, null, 0, TimeUnit.MILLISECONDS); } } } public boolean cancel() { final boolean alreadyReleased = this.released; log.debug("Cancelling request execution"); abortConnection(); return !alreadyReleased; } public boolean isReleased() { return this.released; } public void close() throws IOException { abortConnection(); } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/MainClientExec.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/MainClientExec.j0100644 0000000 0000000 00000060704 12301751703 032313 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.IOException; import java.io.InterruptedIOException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.ConnectionReuseStrategy; import org.apache.http.HttpClientConnection; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthProtocolState; import org.apache.http.auth.AuthState; import org.apache.http.client.AuthenticationStrategy; import org.apache.http.client.NonRepeatableRequestException; import org.apache.http.client.UserTokenHandler; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.protocol.RequestClientConnControl; import org.apache.http.conn.ConnectionKeepAliveStrategy; import org.apache.http.conn.ConnectionRequest; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.conn.routing.BasicRouteDirector; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.HttpRouteDirector; import org.apache.http.conn.routing.RouteTracker; import org.apache.http.entity.BufferedHttpEntity; import org.apache.http.impl.auth.HttpAuthenticator; import org.apache.http.impl.conn.ConnectionShutdownException; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.HttpCoreContext; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpRequestExecutor; import org.apache.http.protocol.ImmutableHttpProcessor; import org.apache.http.protocol.RequestTargetHost; import org.apache.http.util.Args; import org.apache.http.util.EntityUtils; /** * The last request executor in the HTTP request execution chain * that is responsible for execution of request / response * exchanges with the opposite endpoint. * This executor will automatically retry the request in case * of an authentication challenge by an intermediate proxy or * by the target server. * * @since 4.3 */ @Immutable public class MainClientExec implements ClientExecChain { private final Log log = LogFactory.getLog(getClass()); private final HttpRequestExecutor requestExecutor; private final HttpClientConnectionManager connManager; private final ConnectionReuseStrategy reuseStrategy; private final ConnectionKeepAliveStrategy keepAliveStrategy; private final HttpProcessor proxyHttpProcessor; private final AuthenticationStrategy targetAuthStrategy; private final AuthenticationStrategy proxyAuthStrategy; private final HttpAuthenticator authenticator; private final UserTokenHandler userTokenHandler; private final HttpRouteDirector routeDirector; public MainClientExec( final HttpRequestExecutor requestExecutor, final HttpClientConnectionManager connManager, final ConnectionReuseStrategy reuseStrategy, final ConnectionKeepAliveStrategy keepAliveStrategy, final AuthenticationStrategy targetAuthStrategy, final AuthenticationStrategy proxyAuthStrategy, final UserTokenHandler userTokenHandler) { Args.notNull(requestExecutor, "HTTP request executor"); Args.notNull(connManager, "Client connection manager"); Args.notNull(reuseStrategy, "Connection reuse strategy"); Args.notNull(keepAliveStrategy, "Connection keep alive strategy"); Args.notNull(targetAuthStrategy, "Target authentication strategy"); Args.notNull(proxyAuthStrategy, "Proxy authentication strategy"); Args.notNull(userTokenHandler, "User token handler"); this.authenticator = new HttpAuthenticator(); this.proxyHttpProcessor = new ImmutableHttpProcessor( new RequestTargetHost(), new RequestClientConnControl()); this.routeDirector = new BasicRouteDirector(); this.requestExecutor = requestExecutor; this.connManager = connManager; this.reuseStrategy = reuseStrategy; this.keepAliveStrategy = keepAliveStrategy; this.targetAuthStrategy = targetAuthStrategy; this.proxyAuthStrategy = proxyAuthStrategy; this.userTokenHandler = userTokenHandler; } public CloseableHttpResponse execute( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware) throws IOException, HttpException { Args.notNull(route, "HTTP route"); Args.notNull(request, "HTTP request"); Args.notNull(context, "HTTP context"); AuthState targetAuthState = context.getTargetAuthState(); if (targetAuthState == null) { targetAuthState = new AuthState(); context.setAttribute(HttpClientContext.TARGET_AUTH_STATE, targetAuthState); } AuthState proxyAuthState = context.getProxyAuthState(); if (proxyAuthState == null) { proxyAuthState = new AuthState(); context.setAttribute(HttpClientContext.PROXY_AUTH_STATE, proxyAuthState); } if (request instanceof HttpEntityEnclosingRequest) { Proxies.enhanceEntity((HttpEntityEnclosingRequest) request); } Object userToken = context.getUserToken(); final ConnectionRequest connRequest = connManager.requestConnection(route, userToken); if (execAware != null) { if (execAware.isAborted()) { connRequest.cancel(); throw new RequestAbortedException("Request aborted"); } else { execAware.setCancellable(connRequest); } } final RequestConfig config = context.getRequestConfig(); final HttpClientConnection managedConn; try { final int timeout = config.getConnectionRequestTimeout(); managedConn = connRequest.get(timeout > 0 ? timeout : 0, TimeUnit.MILLISECONDS); } catch(final InterruptedException interrupted) { Thread.currentThread().interrupt(); throw new RequestAbortedException("Request aborted", interrupted); } catch(final ExecutionException ex) { Throwable cause = ex.getCause(); if (cause == null) { cause = ex; } throw new RequestAbortedException("Request execution failed", cause); } context.setAttribute(HttpCoreContext.HTTP_CONNECTION, managedConn); if (config.isStaleConnectionCheckEnabled()) { // validate connection if (managedConn.isOpen()) { this.log.debug("Stale connection check"); if (managedConn.isStale()) { this.log.debug("Stale connection detected"); managedConn.close(); } } } final ConnectionHolder connHolder = new ConnectionHolder(this.log, this.connManager, managedConn); try { if (execAware != null) { execAware.setCancellable(connHolder); } HttpResponse response; for (int execCount = 1;; execCount++) { if (execCount > 1 && !Proxies.isRepeatable(request)) { throw new NonRepeatableRequestException("Cannot retry request " + "with a non-repeatable request entity."); } if (execAware != null && execAware.isAborted()) { throw new RequestAbortedException("Request aborted"); } if (!managedConn.isOpen()) { this.log.debug("Opening connection " + route); try { establishRoute(proxyAuthState, managedConn, route, request, context); } catch (final TunnelRefusedException ex) { if (this.log.isDebugEnabled()) { this.log.debug(ex.getMessage()); } response = ex.getResponse(); break; } } final int timeout = config.getSocketTimeout(); if (timeout >= 0) { managedConn.setSocketTimeout(timeout); } if (execAware != null && execAware.isAborted()) { throw new RequestAbortedException("Request aborted"); } if (this.log.isDebugEnabled()) { this.log.debug("Executing request " + request.getRequestLine()); } if (!request.containsHeader(AUTH.WWW_AUTH_RESP)) { if (this.log.isDebugEnabled()) { this.log.debug("Target auth state: " + targetAuthState.getState()); } this.authenticator.generateAuthResponse(request, targetAuthState, context); } if (!request.containsHeader(AUTH.PROXY_AUTH_RESP) && !route.isTunnelled()) { if (this.log.isDebugEnabled()) { this.log.debug("Proxy auth state: " + proxyAuthState.getState()); } this.authenticator.generateAuthResponse(request, proxyAuthState, context); } response = requestExecutor.execute(request, managedConn, context); // The connection is in or can be brought to a re-usable state. if (reuseStrategy.keepAlive(response, context)) { // Set the idle duration of this connection final long duration = keepAliveStrategy.getKeepAliveDuration(response, context); if (this.log.isDebugEnabled()) { final String s; if (duration > 0) { s = "for " + duration + " " + TimeUnit.MILLISECONDS; } else { s = "indefinitely"; } this.log.debug("Connection can be kept alive " + s); } connHolder.setValidFor(duration, TimeUnit.MILLISECONDS); connHolder.markReusable(); } else { connHolder.markNonReusable(); } if (needAuthentication( targetAuthState, proxyAuthState, route, response, context)) { // Make sure the response body is fully consumed, if present final HttpEntity entity = response.getEntity(); if (connHolder.isReusable()) { EntityUtils.consume(entity); } else { managedConn.close(); if (proxyAuthState.getState() == AuthProtocolState.SUCCESS && proxyAuthState.getAuthScheme() != null && proxyAuthState.getAuthScheme().isConnectionBased()) { this.log.debug("Resetting proxy auth state"); proxyAuthState.reset(); } if (targetAuthState.getState() == AuthProtocolState.SUCCESS && targetAuthState.getAuthScheme() != null && targetAuthState.getAuthScheme().isConnectionBased()) { this.log.debug("Resetting target auth state"); targetAuthState.reset(); } } // discard previous auth headers final HttpRequest original = request.getOriginal(); if (!original.containsHeader(AUTH.WWW_AUTH_RESP)) { request.removeHeaders(AUTH.WWW_AUTH_RESP); } if (!original.containsHeader(AUTH.PROXY_AUTH_RESP)) { request.removeHeaders(AUTH.PROXY_AUTH_RESP); } } else { break; } } if (userToken == null) { userToken = userTokenHandler.getUserToken(context); context.setAttribute(HttpClientContext.USER_TOKEN, userToken); } if (userToken != null) { connHolder.setState(userToken); } // check for entity, release connection if possible final HttpEntity entity = response.getEntity(); if (entity == null || !entity.isStreaming()) { // connection not needed and (assumed to be) in re-usable state connHolder.releaseConnection(); return Proxies.enhanceResponse(response, null); } else { return Proxies.enhanceResponse(response, connHolder); } } catch (final ConnectionShutdownException ex) { final InterruptedIOException ioex = new InterruptedIOException( "Connection has been shut down"); ioex.initCause(ex); throw ioex; } catch (final HttpException ex) { connHolder.abortConnection(); throw ex; } catch (final IOException ex) { connHolder.abortConnection(); throw ex; } catch (final RuntimeException ex) { connHolder.abortConnection(); throw ex; } } /** * Establishes the target route. */ void establishRoute( final AuthState proxyAuthState, final HttpClientConnection managedConn, final HttpRoute route, final HttpRequest request, final HttpClientContext context) throws HttpException, IOException { final RequestConfig config = context.getRequestConfig(); final int timeout = config.getConnectTimeout(); final RouteTracker tracker = new RouteTracker(route); int step; do { final HttpRoute fact = tracker.toRoute(); step = this.routeDirector.nextStep(route, fact); switch (step) { case HttpRouteDirector.CONNECT_TARGET: this.connManager.connect( managedConn, route, timeout > 0 ? timeout : 0, context); tracker.connectTarget(route.isSecure()); break; case HttpRouteDirector.CONNECT_PROXY: this.connManager.connect( managedConn, route, timeout > 0 ? timeout : 0, context); final HttpHost proxy = route.getProxyHost(); tracker.connectProxy(proxy, false); break; case HttpRouteDirector.TUNNEL_TARGET: { final boolean secure = createTunnelToTarget( proxyAuthState, managedConn, route, request, context); this.log.debug("Tunnel to target created."); tracker.tunnelTarget(secure); } break; case HttpRouteDirector.TUNNEL_PROXY: { // The most simple example for this case is a proxy chain // of two proxies, where P1 must be tunnelled to P2. // route: Source -> P1 -> P2 -> Target (3 hops) // fact: Source -> P1 -> Target (2 hops) final int hop = fact.getHopCount()-1; // the hop to establish final boolean secure = createTunnelToProxy(route, hop, context); this.log.debug("Tunnel to proxy created."); tracker.tunnelProxy(route.getHopTarget(hop), secure); } break; case HttpRouteDirector.LAYER_PROTOCOL: this.connManager.upgrade(managedConn, route, context); tracker.layerProtocol(route.isSecure()); break; case HttpRouteDirector.UNREACHABLE: throw new HttpException("Unable to establish route: " + "planned = " + route + "; current = " + fact); case HttpRouteDirector.COMPLETE: this.connManager.routeComplete(managedConn, route, context); break; default: throw new IllegalStateException("Unknown step indicator " + step + " from RouteDirector."); } } while (step > HttpRouteDirector.COMPLETE); } /** * Creates a tunnel to the target server. * The connection must be established to the (last) proxy. * A CONNECT request for tunnelling through the proxy will * be created and sent, the response received and checked. * This method does not update the connection with * information about the tunnel, that is left to the caller. */ private boolean createTunnelToTarget( final AuthState proxyAuthState, final HttpClientConnection managedConn, final HttpRoute route, final HttpRequest request, final HttpClientContext context) throws HttpException, IOException { final RequestConfig config = context.getRequestConfig(); final int timeout = config.getConnectTimeout(); final HttpHost target = route.getTargetHost(); final HttpHost proxy = route.getProxyHost(); HttpResponse response; final String authority = target.toHostString(); final HttpRequest connect = new BasicHttpRequest("CONNECT", authority, request.getProtocolVersion()); this.requestExecutor.preProcess(connect, this.proxyHttpProcessor, context); for (;;) { if (!managedConn.isOpen()) { this.connManager.connect( managedConn, route, timeout > 0 ? timeout : 0, context); } connect.removeHeaders(AUTH.PROXY_AUTH_RESP); this.authenticator.generateAuthResponse(connect, proxyAuthState, context); response = this.requestExecutor.execute(connect, managedConn, context); final int status = response.getStatusLine().getStatusCode(); if (status < 200) { throw new HttpException("Unexpected response to CONNECT request: " + response.getStatusLine()); } if (config.isAuthenticationEnabled()) { if (this.authenticator.isAuthenticationRequested(proxy, response, this.proxyAuthStrategy, proxyAuthState, context)) { if (this.authenticator.handleAuthChallenge(proxy, response, this.proxyAuthStrategy, proxyAuthState, context)) { // Retry request if (this.reuseStrategy.keepAlive(response, context)) { this.log.debug("Connection kept alive"); // Consume response content final HttpEntity entity = response.getEntity(); EntityUtils.consume(entity); } else { managedConn.close(); } } else { break; } } else { break; } } } final int status = response.getStatusLine().getStatusCode(); if (status > 299) { // Buffer response content final HttpEntity entity = response.getEntity(); if (entity != null) { response.setEntity(new BufferedHttpEntity(entity)); } managedConn.close(); throw new TunnelRefusedException("CONNECT refused by proxy: " + response.getStatusLine(), response); } // How to decide on security of the tunnelled connection? // The socket factory knows only about the segment to the proxy. // Even if that is secure, the hop to the target may be insecure. // Leave it to derived classes, consider insecure by default here. return false; } /** * Creates a tunnel to an intermediate proxy. * This method is not implemented in this class. * It just throws an exception here. */ private boolean createTunnelToProxy( final HttpRoute route, final int hop, final HttpClientContext context) throws HttpException { // Have a look at createTunnelToTarget and replicate the parts // you need in a custom derived class. If your proxies don't require // authentication, it is not too hard. But for the stock version of // HttpClient, we cannot make such simplifying assumptions and would // have to include proxy authentication code. The HttpComponents team // is currently not in a position to support rarely used code of this // complexity. Feel free to submit patches that refactor the code in // createTunnelToTarget to facilitate re-use for proxy tunnelling. throw new HttpException("Proxy chains are not supported."); } private boolean needAuthentication( final AuthState targetAuthState, final AuthState proxyAuthState, final HttpRoute route, final HttpResponse response, final HttpClientContext context) { final RequestConfig config = context.getRequestConfig(); if (config.isAuthenticationEnabled()) { HttpHost target = context.getTargetHost(); if (target == null) { target = route.getTargetHost(); } if (target.getPort() < 0) { target = new HttpHost( target.getHostName(), route.getTargetHost().getPort(), target.getSchemeName()); } final boolean targetAuthRequested = this.authenticator.isAuthenticationRequested( target, response, this.targetAuthStrategy, targetAuthState, context); HttpHost proxy = route.getProxyHost(); // if proxy is not set use target host instead if (proxy == null) { proxy = route.getTargetHost(); } final boolean proxyAuthRequested = this.authenticator.isAuthenticationRequested( proxy, response, this.proxyAuthStrategy, proxyAuthState, context); if (targetAuthRequested) { return this.authenticator.handleAuthChallenge(target, response, this.targetAuthStrategy, targetAuthState, context); } if (proxyAuthRequested) { return this.authenticator.handleAuthChallenge(proxy, response, this.proxyAuthStrategy, proxyAuthState, context); } } return false; } } ././@LongLink0100644 0000000 0000000 00000000153 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/MinimalClientExec.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/MinimalClientExe0100644 0000000 0000000 00000024677 12301751703 032433 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.IOException; import java.io.InterruptedIOException; import java.net.URI; import java.net.URISyntaxException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.ConnectionReuseStrategy; import org.apache.http.HttpClientConnection; import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.ProtocolException; import org.apache.http.annotation.Immutable; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.protocol.RequestClientConnControl; import org.apache.http.client.utils.URIUtils; import org.apache.http.conn.ConnectionKeepAliveStrategy; import org.apache.http.conn.ConnectionRequest; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.impl.conn.ConnectionShutdownException; import org.apache.http.protocol.HttpCoreContext; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpRequestExecutor; import org.apache.http.protocol.ImmutableHttpProcessor; import org.apache.http.protocol.RequestContent; import org.apache.http.protocol.RequestTargetHost; import org.apache.http.protocol.RequestUserAgent; import org.apache.http.util.Args; import org.apache.http.util.VersionInfo; /** * Request executor that implements the most fundamental aspects of * the HTTP specification and the most straight-forward request / response * exchange with the target server. This executor does not support * execution via proxy and will make no attempts to retry the request * in case of a redirect, authentication challenge or I/O error. * * @since 4.3 */ @Immutable public class MinimalClientExec implements ClientExecChain { private final Log log = LogFactory.getLog(getClass()); private final HttpRequestExecutor requestExecutor; private final HttpClientConnectionManager connManager; private final ConnectionReuseStrategy reuseStrategy; private final ConnectionKeepAliveStrategy keepAliveStrategy; private final HttpProcessor httpProcessor; public MinimalClientExec( final HttpRequestExecutor requestExecutor, final HttpClientConnectionManager connManager, final ConnectionReuseStrategy reuseStrategy, final ConnectionKeepAliveStrategy keepAliveStrategy) { Args.notNull(requestExecutor, "HTTP request executor"); Args.notNull(connManager, "Client connection manager"); Args.notNull(reuseStrategy, "Connection reuse strategy"); Args.notNull(keepAliveStrategy, "Connection keep alive strategy"); this.httpProcessor = new ImmutableHttpProcessor( new RequestContent(), new RequestTargetHost(), new RequestClientConnControl(), new RequestUserAgent(VersionInfo.getUserAgent( "Apache-HttpClient", "org.apache.http.client", getClass()))); this.requestExecutor = requestExecutor; this.connManager = connManager; this.reuseStrategy = reuseStrategy; this.keepAliveStrategy = keepAliveStrategy; } static void rewriteRequestURI( final HttpRequestWrapper request, final HttpRoute route) throws ProtocolException { try { URI uri = request.getURI(); if (uri != null) { // Make sure the request URI is relative if (uri.isAbsolute()) { uri = URIUtils.rewriteURI(uri, null, true); } else { uri = URIUtils.rewriteURI(uri); } request.setURI(uri); } } catch (final URISyntaxException ex) { throw new ProtocolException("Invalid URI: " + request.getRequestLine().getUri(), ex); } } public CloseableHttpResponse execute( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware) throws IOException, HttpException { Args.notNull(route, "HTTP route"); Args.notNull(request, "HTTP request"); Args.notNull(context, "HTTP context"); rewriteRequestURI(request, route); final ConnectionRequest connRequest = connManager.requestConnection(route, null); if (execAware != null) { if (execAware.isAborted()) { connRequest.cancel(); throw new RequestAbortedException("Request aborted"); } else { execAware.setCancellable(connRequest); } } final RequestConfig config = context.getRequestConfig(); final HttpClientConnection managedConn; try { final int timeout = config.getConnectionRequestTimeout(); managedConn = connRequest.get(timeout > 0 ? timeout : 0, TimeUnit.MILLISECONDS); } catch(final InterruptedException interrupted) { Thread.currentThread().interrupt(); throw new RequestAbortedException("Request aborted", interrupted); } catch(final ExecutionException ex) { Throwable cause = ex.getCause(); if (cause == null) { cause = ex; } throw new RequestAbortedException("Request execution failed", cause); } final ConnectionHolder releaseTrigger = new ConnectionHolder(log, connManager, managedConn); try { if (execAware != null) { if (execAware.isAborted()) { releaseTrigger.close(); throw new RequestAbortedException("Request aborted"); } else { execAware.setCancellable(releaseTrigger); } } if (!managedConn.isOpen()) { final int timeout = config.getConnectTimeout(); this.connManager.connect( managedConn, route, timeout > 0 ? timeout : 0, context); this.connManager.routeComplete(managedConn, route, context); } final int timeout = config.getSocketTimeout(); if (timeout >= 0) { managedConn.setSocketTimeout(timeout); } HttpHost target = null; final HttpRequest original = request.getOriginal(); if (original instanceof HttpUriRequest) { final URI uri = ((HttpUriRequest) original).getURI(); if (uri.isAbsolute()) { target = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme()); } } if (target == null) { target = route.getTargetHost(); } context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, target); context.setAttribute(HttpCoreContext.HTTP_REQUEST, request); context.setAttribute(HttpCoreContext.HTTP_CONNECTION, managedConn); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); httpProcessor.process(request, context); final HttpResponse response = requestExecutor.execute(request, managedConn, context); httpProcessor.process(response, context); // The connection is in or can be brought to a re-usable state. if (reuseStrategy.keepAlive(response, context)) { // Set the idle duration of this connection final long duration = keepAliveStrategy.getKeepAliveDuration(response, context); releaseTrigger.setValidFor(duration, TimeUnit.MILLISECONDS); releaseTrigger.markReusable(); } else { releaseTrigger.markNonReusable(); } // check for entity, release connection if possible final HttpEntity entity = response.getEntity(); if (entity == null || !entity.isStreaming()) { // connection not needed and (assumed to be) in re-usable state releaseTrigger.releaseConnection(); return Proxies.enhanceResponse(response, null); } else { return Proxies.enhanceResponse(response, releaseTrigger); } } catch (final ConnectionShutdownException ex) { final InterruptedIOException ioex = new InterruptedIOException( "Connection has been shut down"); ioex.initCause(ex); throw ioex; } catch (final HttpException ex) { releaseTrigger.abortConnection(); throw ex; } catch (final IOException ex) { releaseTrigger.abortConnection(); throw ex; } catch (final RuntimeException ex) { releaseTrigger.abortConnection(); throw ex; } } } ././@LongLink0100644 0000000 0000000 00000000146 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/package-info.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/package-info.jav0100644 0000000 0000000 00000002367 12301751703 032337 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * HTTP request execution chain APIs. */ package org.apache.http.impl.execchain; ././@LongLink0100644 0000000 0000000 00000000146 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/ProtocolExec.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/ProtocolExec.jav0100644 0000000 0000000 00000020452 12301751703 032414 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.ProtocolException; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.URIUtils; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpCoreContext; import org.apache.http.protocol.HttpProcessor; import org.apache.http.util.Args; /** * Request executor in the request execution chain that is responsible * for implementation of HTTP specification requirements. * Internally this executor relies on a {@link HttpProcessor} to populate * requisite HTTP request headers, process HTTP response headers and update * session state in {@link HttpClientContext}. *

* Further responsibilities such as communication with the opposite * endpoint is delegated to the next executor in the request execution * chain. * * @since 4.3 */ @Immutable @SuppressWarnings("deprecation") public class ProtocolExec implements ClientExecChain { private final Log log = LogFactory.getLog(getClass()); private final ClientExecChain requestExecutor; private final HttpProcessor httpProcessor; public ProtocolExec(final ClientExecChain requestExecutor, final HttpProcessor httpProcessor) { Args.notNull(requestExecutor, "HTTP client request executor"); Args.notNull(httpProcessor, "HTTP protocol processor"); this.requestExecutor = requestExecutor; this.httpProcessor = httpProcessor; } void rewriteRequestURI( final HttpRequestWrapper request, final HttpRoute route) throws ProtocolException { try { URI uri = request.getURI(); if (uri != null) { if (route.getProxyHost() != null && !route.isTunnelled()) { // Make sure the request URI is absolute if (!uri.isAbsolute()) { final HttpHost target = route.getTargetHost(); uri = URIUtils.rewriteURI(uri, target, true); } else { uri = URIUtils.rewriteURI(uri); } } else { // Make sure the request URI is relative if (uri.isAbsolute()) { uri = URIUtils.rewriteURI(uri, null, true); } else { uri = URIUtils.rewriteURI(uri); } } request.setURI(uri); } } catch (final URISyntaxException ex) { throw new ProtocolException("Invalid URI: " + request.getRequestLine().getUri(), ex); } } public CloseableHttpResponse execute( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware) throws IOException, HttpException { Args.notNull(route, "HTTP route"); Args.notNull(request, "HTTP request"); Args.notNull(context, "HTTP context"); final HttpRequest original = request.getOriginal(); URI uri = null; if (original instanceof HttpUriRequest) { uri = ((HttpUriRequest) original).getURI(); } else { final String uriString = original.getRequestLine().getUri(); try { uri = URI.create(uriString); } catch (final IllegalArgumentException ex) { if (this.log.isDebugEnabled()) { this.log.debug("Unable to parse '" + uriString + "' as a valid URI; " + "request URI and Host header may be inconsistent", ex); } } } request.setURI(uri); // Re-write request URI if needed rewriteRequestURI(request, route); final HttpParams params = request.getParams(); HttpHost virtualHost = (HttpHost) params.getParameter(ClientPNames.VIRTUAL_HOST); // HTTPCLIENT-1092 - add the port if necessary if (virtualHost != null && virtualHost.getPort() == -1) { final int port = route.getTargetHost().getPort(); if (port != -1) { virtualHost = new HttpHost(virtualHost.getHostName(), port, virtualHost.getSchemeName()); } if (this.log.isDebugEnabled()) { this.log.debug("Using virtual host" + virtualHost); } } HttpHost target = null; if (virtualHost != null) { target = virtualHost; } else { if (uri != null && uri.isAbsolute() && uri.getHost() != null) { target = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme()); } } if (target == null) { target = route.getTargetHost(); } // Get user info from the URI if (uri != null) { final String userinfo = uri.getUserInfo(); if (userinfo != null) { CredentialsProvider credsProvider = context.getCredentialsProvider(); if (credsProvider == null) { credsProvider = new BasicCredentialsProvider(); context.setCredentialsProvider(credsProvider); } credsProvider.setCredentials( new AuthScope(target), new UsernamePasswordCredentials(userinfo)); } } // Run request protocol interceptors context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpCoreContext.HTTP_REQUEST, request); this.httpProcessor.process(request, context); final CloseableHttpResponse response = this.requestExecutor.execute(route, request, context, execAware); try { // Run response protocol interceptors context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response); this.httpProcessor.process(response, context); return response; } catch (final RuntimeException ex) { response.close(); throw ex; } catch (final IOException ex) { response.close(); throw ex; } catch (final HttpException ex) { response.close(); throw ex; } } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/Proxies.java0100644 0000000 0000000 00000007007 12301751703 031601 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.client.methods.CloseableHttpResponse; /** * Execution proxies for HTTP message objects. * * @since 4.3 */ @NotThreadSafe class Proxies { static void enhanceEntity(final HttpEntityEnclosingRequest request) { final HttpEntity entity = request.getEntity(); if (entity != null && !entity.isRepeatable() && !isEnhanced(entity)) { final HttpEntity proxy = (HttpEntity) Proxy.newProxyInstance( HttpEntity.class.getClassLoader(), new Class[] { HttpEntity.class }, new RequestEntityExecHandler(entity)); request.setEntity(proxy); } } static boolean isEnhanced(final HttpEntity entity) { if (entity != null && Proxy.isProxyClass(entity.getClass())) { final InvocationHandler handler = Proxy.getInvocationHandler(entity); return handler instanceof RequestEntityExecHandler; } else { return false; } } static boolean isRepeatable(final HttpRequest request) { if (request instanceof HttpEntityEnclosingRequest) { final HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity(); if (entity != null) { if (isEnhanced(entity)) { final RequestEntityExecHandler handler = (RequestEntityExecHandler) Proxy.getInvocationHandler(entity); if (!handler.isConsumed()) { return true; } } return entity.isRepeatable(); } } return true; } public static CloseableHttpResponse enhanceResponse( final HttpResponse original, final ConnectionHolder connHolder) { return (CloseableHttpResponse) Proxy.newProxyInstance( ResponseProxyHandler.class.getClassLoader(), new Class[] { CloseableHttpResponse.class }, new ResponseProxyHandler(original, connHolder)); } } ././@LongLink0100644 0000000 0000000 00000000146 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/RedirectExec.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/RedirectExec.jav0100644 0000000 0000000 00000017505 12301751703 032361 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.IOException; import java.net.URI; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.ProtocolException; import org.apache.http.annotation.ThreadSafe; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthState; import org.apache.http.client.RedirectException; import org.apache.http.client.RedirectStrategy; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.URIUtils; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.util.Args; import org.apache.http.util.EntityUtils; /** * Request executor in the request execution chain that is responsible * for handling of request redirects. *

* Further responsibilities such as communication with the opposite * endpoint is delegated to the next executor in the request execution * chain. * * @since 4.3 */ @ThreadSafe public class RedirectExec implements ClientExecChain { private final Log log = LogFactory.getLog(getClass()); private final ClientExecChain requestExecutor; private final RedirectStrategy redirectStrategy; private final HttpRoutePlanner routePlanner; public RedirectExec( final ClientExecChain requestExecutor, final HttpRoutePlanner routePlanner, final RedirectStrategy redirectStrategy) { super(); Args.notNull(requestExecutor, "HTTP client request executor"); Args.notNull(routePlanner, "HTTP route planner"); Args.notNull(redirectStrategy, "HTTP redirect strategy"); this.requestExecutor = requestExecutor; this.routePlanner = routePlanner; this.redirectStrategy = redirectStrategy; } public CloseableHttpResponse execute( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware) throws IOException, HttpException { Args.notNull(route, "HTTP route"); Args.notNull(request, "HTTP request"); Args.notNull(context, "HTTP context"); final List redirectLocations = context.getRedirectLocations(); if (redirectLocations != null) { redirectLocations.clear(); } final RequestConfig config = context.getRequestConfig(); final int maxRedirects = config.getMaxRedirects() > 0 ? config.getMaxRedirects() : 50; HttpRoute currentRoute = route; HttpRequestWrapper currentRequest = request; for (int redirectCount = 0;;) { final CloseableHttpResponse response = requestExecutor.execute( currentRoute, currentRequest, context, execAware); try { if (config.isRedirectsEnabled() && this.redirectStrategy.isRedirected(currentRequest, response, context)) { if (redirectCount >= maxRedirects) { throw new RedirectException("Maximum redirects ("+ maxRedirects + ") exceeded"); } redirectCount++; final HttpRequest redirect = this.redirectStrategy.getRedirect( currentRequest, response, context); if (!redirect.headerIterator().hasNext()) { final HttpRequest original = request.getOriginal(); redirect.setHeaders(original.getAllHeaders()); } currentRequest = HttpRequestWrapper.wrap(redirect); if (currentRequest instanceof HttpEntityEnclosingRequest) { Proxies.enhanceEntity((HttpEntityEnclosingRequest) currentRequest); } final URI uri = currentRequest.getURI(); final HttpHost newTarget = URIUtils.extractHost(uri); if (newTarget == null) { throw new ProtocolException("Redirect URI does not specify a valid host name: " + uri); } // Reset virtual host and auth states if redirecting to another host if (!currentRoute.getTargetHost().equals(newTarget)) { final AuthState targetAuthState = context.getTargetAuthState(); if (targetAuthState != null) { this.log.debug("Resetting target auth state"); targetAuthState.reset(); } final AuthState proxyAuthState = context.getProxyAuthState(); if (proxyAuthState != null) { final AuthScheme authScheme = proxyAuthState.getAuthScheme(); if (authScheme != null && authScheme.isConnectionBased()) { this.log.debug("Resetting proxy auth state"); proxyAuthState.reset(); } } } currentRoute = this.routePlanner.determineRoute(newTarget, currentRequest, context); if (this.log.isDebugEnabled()) { this.log.debug("Redirecting to '" + uri + "' via " + currentRoute); } EntityUtils.consume(response.getEntity()); response.close(); } else { return response; } } catch (final RuntimeException ex) { response.close(); throw ex; } catch (final IOException ex) { response.close(); throw ex; } catch (final HttpException ex) { // Protocol exception related to a direct. // The underlying connection may still be salvaged. try { EntityUtils.consume(response.getEntity()); } catch (final IOException ioex) { this.log.debug("I/O error while releasing connection", ioex); } finally { response.close(); } throw ex; } } } } ././@LongLink0100644 0000000 0000000 00000000161 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/RequestAbortedException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/RequestAbortedEx0100644 0000000 0000000 00000003423 12301751703 032454 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.InterruptedIOException; import org.apache.http.annotation.Immutable; /** * Signals that the request has been aborted. * * @since 4.3 */ @Immutable public class RequestAbortedException extends InterruptedIOException { private static final long serialVersionUID = 4973849966012490112L; public RequestAbortedException(final String message) { super(message); } public RequestAbortedException(final String message, final Throwable cause) { super(message); if (cause != null) { initCause(cause); } } } ././@LongLink0100644 0000000 0000000 00000000162 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/RequestEntityExecHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/RequestEntityExe0100644 0000000 0000000 00000005330 12301751703 032514 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.OutputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.http.HttpEntity; import org.apache.http.annotation.NotThreadSafe; /** * A wrapper class for {@link HttpEntity} enclosed in a request message. * * @since 4.3 */ @NotThreadSafe class RequestEntityExecHandler implements InvocationHandler { private static final Method WRITE_TO_METHOD; static { try { WRITE_TO_METHOD = HttpEntity.class.getMethod("writeTo", OutputStream.class); } catch (final NoSuchMethodException ex) { throw new Error(ex); } } private final HttpEntity original; private boolean consumed = false; RequestEntityExecHandler(final HttpEntity original) { super(); this.original = original; } public HttpEntity getOriginal() { return original; } public boolean isConsumed() { return consumed; } public Object invoke( final Object proxy, final Method method, final Object[] args) throws Throwable { try { if (method.equals(WRITE_TO_METHOD)) { this.consumed = true; } return method.invoke(original, args); } catch (final InvocationTargetException ex) { final Throwable cause = ex.getCause(); if (cause != null) { throw cause; } else { throw ex; } } } } ././@LongLink0100644 0000000 0000000 00000000157 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/ResponseEntityWrapper.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/ResponseEntityWr0100644 0000000 0000000 00000010217 12301751703 032531 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.SocketException; import org.apache.http.HttpEntity; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.conn.EofSensorInputStream; import org.apache.http.conn.EofSensorWatcher; import org.apache.http.entity.HttpEntityWrapper; /** * A wrapper class for {@link HttpEntity} enclosed in a response message. * * @since 4.3 */ @NotThreadSafe class ResponseEntityWrapper extends HttpEntityWrapper implements EofSensorWatcher { private final ConnectionHolder connReleaseTrigger; public ResponseEntityWrapper( final HttpEntity entity, final ConnectionHolder connReleaseTrigger) { super(entity); this.connReleaseTrigger = connReleaseTrigger; } private void cleanup() { if (this.connReleaseTrigger != null) { this.connReleaseTrigger.abortConnection(); } } public void releaseConnection() throws IOException { if (this.connReleaseTrigger != null) { try { if (this.connReleaseTrigger.isReusable()) { this.connReleaseTrigger.releaseConnection(); } } finally { cleanup(); } } } @Override public boolean isRepeatable() { return false; } @Override public InputStream getContent() throws IOException { return new EofSensorInputStream(this.wrappedEntity.getContent(), this); } @Deprecated @Override public void consumeContent() throws IOException { releaseConnection(); } @Override public void writeTo(final OutputStream outstream) throws IOException { try { this.wrappedEntity.writeTo(outstream); releaseConnection(); } finally { cleanup(); } } public boolean eofDetected(final InputStream wrapped) throws IOException { try { // there may be some cleanup required, such as // reading trailers after the response body: wrapped.close(); releaseConnection(); } finally { cleanup(); } return false; } public boolean streamClosed(final InputStream wrapped) throws IOException { try { final boolean open = connReleaseTrigger != null && !connReleaseTrigger.isReleased(); // this assumes that closing the stream will // consume the remainder of the response body: try { wrapped.close(); releaseConnection(); } catch (final SocketException ex) { if (open) { throw ex; } } } finally { cleanup(); } return false; } public boolean streamAbort(final InputStream wrapped) throws IOException { cleanup(); return false; } } ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/ResponseProxyHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/ResponseProxyHan0100644 0000000 0000000 00000006275 12301751703 032525 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.Closeable; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.annotation.NotThreadSafe; /** * A proxy class for {@link HttpResponse} that can be used to release client connection * associated with the original response. * * @since 4.3 */ @NotThreadSafe class ResponseProxyHandler implements InvocationHandler { private static final Method CLOSE_METHOD; static { try { CLOSE_METHOD = Closeable.class.getMethod("close"); } catch (final NoSuchMethodException ex) { throw new Error(ex); } } private final HttpResponse original; private final ConnectionHolder connHolder; ResponseProxyHandler( final HttpResponse original, final ConnectionHolder connHolder) { super(); this.original = original; this.connHolder = connHolder; final HttpEntity entity = original.getEntity(); if (entity != null && entity.isStreaming() && connHolder != null) { this.original.setEntity(new ResponseEntityWrapper(entity, connHolder)); } } public void close() throws IOException { if (this.connHolder != null) { this.connHolder.abortConnection(); } } public Object invoke( final Object proxy, final Method method, final Object[] args) throws Throwable { if (method.equals(CLOSE_METHOD)) { close(); return null; } else { try { return method.invoke(original, args); } catch (final InvocationTargetException ex) { final Throwable cause = ex.getCause(); if (cause != null) { throw cause; } else { throw ex; } } } } } httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/RetryExec.java0100644 0000000 0000000 00000012310 12301751703 032053 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpException; import org.apache.http.NoHttpResponseException; import org.apache.http.annotation.Immutable; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.NonRepeatableRequestException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.util.Args; /** * Request executor in the request execution chain that is responsible * for making a decision whether a request failed due to an I/O error * should be re-executed. *

* Further responsibilities such as communication with the opposite * endpoint is delegated to the next executor in the request execution * chain. * * @since 4.3 */ @Immutable public class RetryExec implements ClientExecChain { private final Log log = LogFactory.getLog(getClass()); private final ClientExecChain requestExecutor; private final HttpRequestRetryHandler retryHandler; public RetryExec( final ClientExecChain requestExecutor, final HttpRequestRetryHandler retryHandler) { Args.notNull(requestExecutor, "HTTP request executor"); Args.notNull(retryHandler, "HTTP request retry handler"); this.requestExecutor = requestExecutor; this.retryHandler = retryHandler; } public CloseableHttpResponse execute( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware) throws IOException, HttpException { Args.notNull(route, "HTTP route"); Args.notNull(request, "HTTP request"); Args.notNull(context, "HTTP context"); final Header[] origheaders = request.getAllHeaders(); for (int execCount = 1;; execCount++) { try { return this.requestExecutor.execute(route, request, context, execAware); } catch (final IOException ex) { if (execAware != null && execAware.isAborted()) { this.log.debug("Request has been aborted"); throw ex; } if (retryHandler.retryRequest(ex, execCount, context)) { if (this.log.isInfoEnabled()) { this.log.info("I/O exception ("+ ex.getClass().getName() + ") caught when processing request to " + route + ": " + ex.getMessage()); } if (this.log.isDebugEnabled()) { this.log.debug(ex.getMessage(), ex); } if (!Proxies.isRepeatable(request)) { this.log.debug("Cannot retry non-repeatable request"); throw new NonRepeatableRequestException("Cannot retry request " + "with a non-repeatable request entity", ex); } request.setHeaders(origheaders); if (this.log.isInfoEnabled()) { this.log.info("Retrying request to " + route); } } else { if (ex instanceof NoHttpResponseException) { final NoHttpResponseException updatedex = new NoHttpResponseException( route.getTargetHost().toHostString() + " failed to respond"); updatedex.setStackTrace(ex.getStackTrace()); throw updatedex; } else { throw ex; } } } } } } ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/ServiceUnavailableRetryExec.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/ServiceUnavailab0100644 0000000 0000000 00000010344 12301751703 032451 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.IOException; import java.io.InterruptedIOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpException; import org.apache.http.annotation.Immutable; import org.apache.http.client.ServiceUnavailableRetryStrategy; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.util.Args; /** * Request executor in the request execution chain that is responsible * for making a decision whether a request that received a non-2xx response * from the target server should be re-executed. *

* Further responsibilities such as communication with the opposite * endpoint is delegated to the next executor in the request execution * chain. * * @since 4.3 */ @Immutable public class ServiceUnavailableRetryExec implements ClientExecChain { private final Log log = LogFactory.getLog(getClass()); private final ClientExecChain requestExecutor; private final ServiceUnavailableRetryStrategy retryStrategy; public ServiceUnavailableRetryExec( final ClientExecChain requestExecutor, final ServiceUnavailableRetryStrategy retryStrategy) { super(); Args.notNull(requestExecutor, "HTTP request executor"); Args.notNull(retryStrategy, "Retry strategy"); this.requestExecutor = requestExecutor; this.retryStrategy = retryStrategy; } public CloseableHttpResponse execute( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware) throws IOException, HttpException { final Header[] origheaders = request.getAllHeaders(); for (int c = 1;; c++) { final CloseableHttpResponse response = this.requestExecutor.execute( route, request, context, execAware); try { if (this.retryStrategy.retryRequest(response, c, context)) { response.close(); final long nextInterval = this.retryStrategy.getRetryInterval(); if (nextInterval > 0) { try { this.log.trace("Wait for " + nextInterval); Thread.sleep(nextInterval); } catch (final InterruptedException e) { Thread.currentThread().interrupt(); throw new InterruptedIOException(); } } request.setHeaders(origheaders); } else { return response; } } catch (final RuntimeException ex) { response.close(); throw ex; } } } } ././@LongLink0100644 0000000 0000000 00000000160 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/TunnelRefusedException.javahttpcomponents-client-4.3.3/httpclient/src/main/java/org/apache/http/impl/execchain/TunnelRefusedExc0100644 0000000 0000000 00000003501 12301751703 032446 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import org.apache.http.HttpException; import org.apache.http.HttpResponse; import org.apache.http.annotation.Immutable; /** * Signals that the tunnel request was rejected by the proxy host. * * @since 4.0 */ @Immutable public class TunnelRefusedException extends HttpException { private static final long serialVersionUID = -8646722842745617323L; private final HttpResponse response; public TunnelRefusedException(final String message, final HttpResponse response) { super(message); this.response = response; } public HttpResponse getResponse() { return this.response; } } httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/0040755 0000000 0000000 00000000000 12301751661 023526 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/0040755 0000000 0000000 00000000000 12301751661 024315 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/0040755 0000000 0000000 00000000000 12301751661 025536 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/0040755 0000000 0000000 00000000000 12301751663 026517 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/auth/0040755 0000000 0000000 00000000000 12301751662 027457 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/auth/params/0040755 0000000 0000000 00000000000 12301751663 030743 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000157 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/auth/params/AuthParamBean.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/auth/params/AuthPara0100644 0000000 0000000 00000003660 12301751663 032375 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth.params; import org.apache.http.params.HttpAbstractParamBean; import org.apache.http.params.HttpParams; /** * This is a Java Bean class that can be used to wrap an instance of * {@link HttpParams} and manipulate HTTP authentication parameters * using Java Beans conventions. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.client.config.RequestConfig} * and constructor parameters of * {@link org.apache.http.auth.AuthSchemeProvider}s. */ @Deprecated public class AuthParamBean extends HttpAbstractParamBean { public AuthParamBean (final HttpParams params) { super(params); } public void setCredentialCharset (final String charset) { AuthParams.setCredentialCharset(params, charset); } } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/auth/params/AuthParams.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/auth/params/AuthPara0100644 0000000 0000000 00000005234 12301751663 032374 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth.params; import org.apache.http.annotation.Immutable; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HTTP; import org.apache.http.util.Args; /** * An adaptor for manipulating HTTP authentication parameters * in {@link HttpParams}. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.client.config.RequestConfig} * and constructor parameters of * {@link org.apache.http.auth.AuthSchemeProvider}s. */ @Immutable @Deprecated public final class AuthParams { private AuthParams() { super(); } /** * Obtains the charset for encoding * {@link org.apache.http.auth.Credentials}.If not configured, * {@link HTTP#DEFAULT_PROTOCOL_CHARSET}is used instead. * * @return The charset */ public static String getCredentialCharset(final HttpParams params) { Args.notNull(params, "HTTP parameters"); String charset = (String) params.getParameter (AuthPNames.CREDENTIAL_CHARSET); if (charset == null) { charset = HTTP.DEF_PROTOCOL_CHARSET.name(); } return charset; } /** * Sets the charset to be used when encoding * {@link org.apache.http.auth.Credentials}. * * @param charset The charset */ public static void setCredentialCharset(final HttpParams params, final String charset) { Args.notNull(params, "HTTP parameters"); params.setParameter(AuthPNames.CREDENTIAL_CHARSET, charset); } } httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/0040755 0000000 0000000 00000000000 12301751662 027774 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000162 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/AuthenticationHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/Authenticatio0100644 0000000 0000000 00000007273 12301751662 032526 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import java.util.Map; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.protocol.HttpContext; /** /** * A handler for determining if an HTTP response represents an authentication * challenge that was sent back to the client as a result of authentication * failure. *

* Implementations of this interface must be thread-safe. Access to shared * data must be synchronized as methods of this interface may be executed * from multiple threads. * * @since 4.0 * * @deprecated (4.2) use {@link AuthenticationStrategy} */ @Deprecated public interface AuthenticationHandler { /** * Determines if the given HTTP response response represents * an authentication challenge that was sent back as a result * of authentication failure * @param response HTTP response. * @param context HTTP context. * @return true if user authentication is required, * false otherwise. */ boolean isAuthenticationRequested( HttpResponse response, HttpContext context); /** * Extracts from the given HTTP response a collection of authentication * challenges, each of which represents an authentication scheme supported * by the authentication host. * * @param response HTTP response. * @param context HTTP context. * @return a collection of challenges keyed by names of corresponding * authentication schemes. * @throws MalformedChallengeException if one of the authentication * challenges is not valid or malformed. */ Map getChallenges( HttpResponse response, HttpContext context) throws MalformedChallengeException; /** * Selects one authentication challenge out of all available and * creates and generates {@link AuthScheme} instance capable of * processing that challenge. * @param challenges collection of challenges. * @param response HTTP response. * @param context HTTP context. * @return authentication scheme to use for authentication. * @throws AuthenticationException if an authentication scheme * could not be selected. */ AuthScheme selectScheme( Map challenges, HttpResponse response, HttpContext context) throws AuthenticationException; } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/RedirectHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/RedirectHandl0100644 0000000 0000000 00000005306 12301751662 032430 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import java.net.URI; import org.apache.http.HttpResponse; import org.apache.http.ProtocolException; import org.apache.http.protocol.HttpContext; /** * A handler for determining if an HTTP request should be redirected to * a new location in response to an HTTP response received from the target * server. *

* Implementations of this interface must be thread-safe. Access to shared * data must be synchronized as methods of this interface may be executed * from multiple threads. * * @since 4.0 * * @deprecated (4.1) use {@link RedirectStrategy} */ @Deprecated public interface RedirectHandler { /** * Determines if a request should be redirected to a new location * given the response from the target server. * * @param response the response received from the target server * @param context the context for the request execution * * @return true if the request should be redirected, false * otherwise */ boolean isRedirectRequested(HttpResponse response, HttpContext context); /** * Determines the location request is expected to be redirected to * given the response from the target server and the current request * execution context. * * @param response the response received from the target server * @param context the context for the request execution * * @return redirect URI */ URI getLocationURI(HttpResponse response, HttpContext context) throws ProtocolException; } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/RequestDirector.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/RequestDirect0100644 0000000 0000000 00000005633 12301751662 032506 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client; import java.io.IOException; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.protocol.HttpContext; /** * A client-side request director. * The director decides which steps are necessary to execute a request. * It establishes connections and optionally processes redirects and * authentication challenges. The director may therefore generate and * send a sequence of requests in order to execute one initial request. * * @since 4.0 * * @deprecated (4.3) No longer used */ @Deprecated public interface RequestDirector { /** * Executes a request. *
Note: * For the time being, a new director is instantiated for each request. * This is the same behavior as for HttpMethodDirector * in HttpClient 3. * * @param target the target host for the request. * Implementations may accept null * if they can still determine a route, for example * to a default target or by inspecting the request. * @param request the request to execute * @param context the context for executing the request * * @return the final response to the request. * This is never an intermediate response with status code 1xx. * * @throws HttpException in case of a problem * @throws IOException in case of an IO problem * or if the connection was aborted */ HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws HttpException, IOException; } httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/params/0040755 0000000 0000000 00000000000 12301751662 031257 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/params/AuthPolicy.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/params/AuthPo0100644 0000000 0000000 00000004502 12301751662 032400 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.params; import org.apache.http.annotation.Immutable; /** * Standard authentication schemes supported by HttpClient. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.client.config.AuthSchemes}. */ @Deprecated @Immutable public final class AuthPolicy { private AuthPolicy() { super(); } /** * The NTLM scheme is a proprietary Microsoft Windows Authentication * protocol (considered to be the most secure among currently supported * authentication schemes). */ public static final String NTLM = "NTLM"; /** * Digest authentication scheme as defined in RFC2617. */ public static final String DIGEST = "Digest"; /** * Basic authentication scheme as defined in RFC2617 (considered inherently * insecure, but most widely supported) */ public static final String BASIC = "Basic"; /** * SPNEGO Authentication scheme. * * @since 4.1 */ public static final String SPNEGO = "negotiate"; /** * Kerberos Authentication scheme. * * @since 4.2 */ public static final String KERBEROS = "Kerberos"; } ././@LongLink0100644 0000000 0000000 00000000163 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/params/ClientParamBean.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/params/Client0100644 0000000 0000000 00000007026 12301751662 032422 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.params; import java.util.Collection; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.params.HttpAbstractParamBean; import org.apache.http.params.HttpParams; /** * This is a Java Bean class that can be used to wrap an instance of * {@link HttpParams} and manipulate HTTP client parameters using * Java Beans conventions. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.client.config.RequestConfig}. */ @Deprecated @NotThreadSafe public class ClientParamBean extends HttpAbstractParamBean { public ClientParamBean (final HttpParams params) { super(params); } /** * @deprecated (4.2) do not use. */ @Deprecated public void setConnectionManagerFactoryClassName (final String factory) { params.setParameter(ClientPNames.CONNECTION_MANAGER_FACTORY_CLASS_NAME, factory); } public void setHandleRedirects (final boolean handle) { params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, handle); } public void setRejectRelativeRedirect (final boolean reject) { params.setBooleanParameter(ClientPNames.REJECT_RELATIVE_REDIRECT, reject); } public void setMaxRedirects (final int maxRedirects) { params.setIntParameter(ClientPNames.MAX_REDIRECTS, maxRedirects); } public void setAllowCircularRedirects (final boolean allow) { params.setBooleanParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, allow); } public void setHandleAuthentication (final boolean handle) { params.setBooleanParameter(ClientPNames.HANDLE_AUTHENTICATION, handle); } public void setCookiePolicy (final String policy) { params.setParameter(ClientPNames.COOKIE_POLICY, policy); } public void setVirtualHost (final HttpHost host) { params.setParameter(ClientPNames.VIRTUAL_HOST, host); } public void setDefaultHeaders (final Collection

headers) { params.setParameter(ClientPNames.DEFAULT_HEADERS, headers); } public void setDefaultHost (final HttpHost host) { params.setParameter(ClientPNames.DEFAULT_HOST, host); } /** * @since 4.2 */ public void setConnectionManagerTimeout(final long timeout) { params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUT, timeout); } } ././@LongLink0100644 0000000 0000000 00000000160 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/params/CookiePolicy.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/params/Cookie0100644 0000000 0000000 00000004473 12301751662 032420 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.params; import org.apache.http.annotation.Immutable; /** * Standard cookie specifications supported by HttpClient. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.client.config.CookieSpecs}. */ @Deprecated @Immutable public final class CookiePolicy { /** * The policy that provides high degree of compatibilty * with common cookie management of popular HTTP agents. */ public static final String BROWSER_COMPATIBILITY = "compatibility"; /** * The Netscape cookie draft compliant policy. */ public static final String NETSCAPE = "netscape"; /** * The RFC 2109 compliant policy. */ public static final String RFC_2109 = "rfc2109"; /** * The RFC 2965 compliant policy. */ public static final String RFC_2965 = "rfc2965"; /** * The default 'best match' policy. */ public static final String BEST_MATCH = "best-match"; /** * The policy that ignores cookies. * * @since 4.1-beta1 */ public static final String IGNORE_COOKIES = "ignoreCookies"; private CookiePolicy() { super(); } } ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/params/HttpClientParams.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/params/HttpCl0100644 0000000 0000000 00000010177 12301751662 032403 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.params; import org.apache.http.annotation.Immutable; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.util.Args; /** * An adaptor for manipulating HTTP client parameters in {@link HttpParams}. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.client.config.RequestConfig} */ @Deprecated @Immutable public class HttpClientParams { private HttpClientParams() { super(); } public static boolean isRedirecting(final HttpParams params) { Args.notNull(params, "HTTP parameters"); return params.getBooleanParameter (ClientPNames.HANDLE_REDIRECTS, true); } public static void setRedirecting(final HttpParams params, final boolean value) { Args.notNull(params, "HTTP parameters"); params.setBooleanParameter (ClientPNames.HANDLE_REDIRECTS, value); } public static boolean isAuthenticating(final HttpParams params) { Args.notNull(params, "HTTP parameters"); return params.getBooleanParameter (ClientPNames.HANDLE_AUTHENTICATION, true); } public static void setAuthenticating(final HttpParams params, final boolean value) { Args.notNull(params, "HTTP parameters"); params.setBooleanParameter (ClientPNames.HANDLE_AUTHENTICATION, value); } public static String getCookiePolicy(final HttpParams params) { Args.notNull(params, "HTTP parameters"); final String cookiePolicy = (String) params.getParameter(ClientPNames.COOKIE_POLICY); if (cookiePolicy == null) { return CookiePolicy.BEST_MATCH; } return cookiePolicy; } public static void setCookiePolicy(final HttpParams params, final String cookiePolicy) { Args.notNull(params, "HTTP parameters"); params.setParameter(ClientPNames.COOKIE_POLICY, cookiePolicy); } /** * Set the parameter {@code ClientPNames.CONN_MANAGER_TIMEOUT}. * * @since 4.2 */ public static void setConnectionManagerTimeout(final HttpParams params, final long timeout) { Args.notNull(params, "HTTP parameters"); params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUT, timeout); } /** * Get the connectiion manager timeout value. * This is defined by the parameter {@code ClientPNames.CONN_MANAGER_TIMEOUT}. * Failing that it uses the parameter {@code CoreConnectionPNames.CONNECTION_TIMEOUT} * which defaults to 0 if not defined. * * @since 4.2 * @return the timeout value */ public static long getConnectionManagerTimeout(final HttpParams params) { Args.notNull(params, "HTTP parameters"); final Long timeout = (Long) params.getParameter(ClientPNames.CONN_MANAGER_TIMEOUT); if (timeout != null) { return timeout.longValue(); } return HttpConnectionParams.getConnectionTimeout(params); } } httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/protocol/0040755 0000000 0000000 00000000000 12301751662 031635 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000163 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/protocol/ClientContext.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/protocol/Clie0100644 0000000 0000000 00000011321 12301751662 032427 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; /** * {@link org.apache.http.protocol.HttpContext} attribute names for * client side HTTP protocol processing. * * @since 4.0 * * @deprecated (4.3) use {@link HttpClientContext}. */ @Deprecated public interface ClientContext { /** * Attribute name of a {@link org.apache.http.conn.routing.RouteInfo} * object that represents the actual connection route. * * @since 4.3 */ public static final String ROUTE = "http.route"; /** * Attribute name of a {@link org.apache.http.conn.scheme.Scheme} * object that represents the actual protocol scheme registry. */ @Deprecated public static final String SCHEME_REGISTRY = "http.scheme-registry"; /** * Attribute name of a {@link org.apache.http.config.Lookup} object that represents * the actual {@link org.apache.http.cookie.CookieSpecRegistry} registry. */ public static final String COOKIESPEC_REGISTRY = "http.cookiespec-registry"; /** * Attribute name of a {@link org.apache.http.cookie.CookieSpec} * object that represents the actual cookie specification. */ public static final String COOKIE_SPEC = "http.cookie-spec"; /** * Attribute name of a {@link org.apache.http.cookie.CookieOrigin} * object that represents the actual details of the origin server. */ public static final String COOKIE_ORIGIN = "http.cookie-origin"; /** * Attribute name of a {@link org.apache.http.client.CookieStore} * object that represents the actual cookie store. */ public static final String COOKIE_STORE = "http.cookie-store"; /** * Attribute name of a {@link org.apache.http.client.CredentialsProvider} * object that represents the actual credentials provider. */ public static final String CREDS_PROVIDER = "http.auth.credentials-provider"; /** * Attribute name of a {@link org.apache.http.client.AuthCache} object * that represents the auth scheme cache. */ public static final String AUTH_CACHE = "http.auth.auth-cache"; /** * Attribute name of a {@link org.apache.http.auth.AuthState} * object that represents the actual target authentication state. */ public static final String TARGET_AUTH_STATE = "http.auth.target-scope"; /** * Attribute name of a {@link org.apache.http.auth.AuthState} * object that represents the actual proxy authentication state. */ public static final String PROXY_AUTH_STATE = "http.auth.proxy-scope"; /** * @deprecated (4.1) do not use */ @Deprecated public static final String AUTH_SCHEME_PREF = "http.auth.scheme-pref"; /** * Attribute name of a {@link java.lang.Object} object that represents * the actual user identity such as user {@link java.security.Principal}. */ public static final String USER_TOKEN = "http.user-token"; /** * Attribute name of a {@link org.apache.http.config.Lookup} object that represents * the actual {@link org.apache.http.auth.AuthSchemeRegistry} registry. */ public static final String AUTHSCHEME_REGISTRY = "http.authscheme-registry"; public static final String SOCKET_FACTORY_REGISTRY = "http.socket-factory-registry"; /** * Attribute name of a {@link org.apache.http.client.config.RequestConfig} object that * represents the actual request configuration. * * @since 4.3 */ public static final String REQUEST_CONFIG = "http.request-config"; } ././@LongLink0100644 0000000 0000000 00000000175 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/protocol/ClientContextConfigurer.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/protocol/Clie0100644 0000000 0000000 00000004745 12301751662 032443 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AuthSchemeRegistry; import org.apache.http.client.CookieStore; import org.apache.http.client.CredentialsProvider; import org.apache.http.cookie.CookieSpecRegistry; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Configuration facade for {@link HttpContext} instances. * * @since 4.0 * * @deprecated (4.3) use {@link HttpClientContext} */ @NotThreadSafe @Deprecated public class ClientContextConfigurer implements ClientContext { private final HttpContext context; public ClientContextConfigurer (final HttpContext context) { Args.notNull(context, "HTTP context"); this.context = context; } public void setCookieSpecRegistry(final CookieSpecRegistry registry) { this.context.setAttribute(COOKIESPEC_REGISTRY, registry); } public void setAuthSchemeRegistry(final AuthSchemeRegistry registry) { this.context.setAttribute(AUTHSCHEME_REGISTRY, registry); } public void setCookieStore(final CookieStore store) { this.context.setAttribute(COOKIE_STORE, store); } public void setCredentialsProvider(final CredentialsProvider provider) { this.context.setAttribute(CREDS_PROVIDER, provider); } } ././@LongLink0100644 0000000 0000000 00000000177 12302131605 011631 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/protocol/RequestAuthenticationBase.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/protocol/Requ0100644 0000000 0000000 00000011431 12301751662 032471 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.util.Queue; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.auth.AuthOption; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthState; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.ContextAwareAuthScheme; import org.apache.http.auth.Credentials; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Asserts; @Deprecated abstract class RequestAuthenticationBase implements HttpRequestInterceptor { final Log log = LogFactory.getLog(getClass()); public RequestAuthenticationBase() { super(); } void process( final AuthState authState, final HttpRequest request, final HttpContext context) { AuthScheme authScheme = authState.getAuthScheme(); Credentials creds = authState.getCredentials(); switch (authState.getState()) { case FAILURE: return; case SUCCESS: ensureAuthScheme(authScheme); if (authScheme.isConnectionBased()) { return; } break; case CHALLENGED: final Queue authOptions = authState.getAuthOptions(); if (authOptions != null) { while (!authOptions.isEmpty()) { final AuthOption authOption = authOptions.remove(); authScheme = authOption.getAuthScheme(); creds = authOption.getCredentials(); authState.update(authScheme, creds); if (this.log.isDebugEnabled()) { this.log.debug("Generating response to an authentication challenge using " + authScheme.getSchemeName() + " scheme"); } try { final Header header = authenticate(authScheme, creds, request, context); request.addHeader(header); break; } catch (final AuthenticationException ex) { if (this.log.isWarnEnabled()) { this.log.warn(authScheme + " authentication error: " + ex.getMessage()); } } } return; } else { ensureAuthScheme(authScheme); } } if (authScheme != null) { try { final Header header = authenticate(authScheme, creds, request, context); request.addHeader(header); } catch (final AuthenticationException ex) { if (this.log.isErrorEnabled()) { this.log.error(authScheme + " authentication error: " + ex.getMessage()); } } } } private void ensureAuthScheme(final AuthScheme authScheme) { Asserts.notNull(authScheme, "Auth scheme"); } private Header authenticate( final AuthScheme authScheme, final Credentials creds, final HttpRequest request, final HttpContext context) throws AuthenticationException { Asserts.notNull(authScheme, "Auth scheme"); if (authScheme instanceof ContextAwareAuthScheme) { return ((ContextAwareAuthScheme) authScheme).authenticate(creds, request, context); } else { return authScheme.authenticate(creds, request); } } } ././@LongLink0100644 0000000 0000000 00000000200 12302131605 011614 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/protocol/RequestProxyAuthentication.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/protocol/Requ0100644 0000000 0000000 00000006254 12301751662 032500 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.io.IOException; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthState; import org.apache.http.conn.HttpRoutedConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.protocol.ExecutionContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Generates authentication header for the proxy host, if required, * based on the actual state of the HTTP authentication context. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.impl.auth.HttpAuthenticator}. */ @Deprecated @Immutable public class RequestProxyAuthentication extends RequestAuthenticationBase { public RequestProxyAuthentication() { super(); } public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { Args.notNull(request, "HTTP request"); Args.notNull(context, "HTTP context"); if (request.containsHeader(AUTH.PROXY_AUTH_RESP)) { return; } final HttpRoutedConnection conn = (HttpRoutedConnection) context.getAttribute( ExecutionContext.HTTP_CONNECTION); if (conn == null) { this.log.debug("HTTP connection not set in the context"); return; } final HttpRoute route = conn.getRoute(); if (route.isTunnelled()) { return; } // Obtain authentication state final AuthState authState = (AuthState) context.getAttribute( ClientContext.PROXY_AUTH_STATE); if (authState == null) { this.log.debug("Proxy auth state not set in the context"); return; } if (this.log.isDebugEnabled()) { this.log.debug("Proxy auth state: " + authState.getState()); } process(authState, request, context); } } ././@LongLink0100644 0000000 0000000 00000000201 12302131605 011615 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/protocol/RequestTargetAuthentication.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/protocol/Requ0100644 0000000 0000000 00000005465 12301751662 032503 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.io.IOException; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthState; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Generates authentication header for the target host, if required, * based on the actual state of the HTTP authentication context. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.impl.auth.HttpAuthenticator}. */ @Deprecated @Immutable public class RequestTargetAuthentication extends RequestAuthenticationBase { public RequestTargetAuthentication() { super(); } public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { Args.notNull(request, "HTTP request"); Args.notNull(context, "HTTP context"); final String method = request.getRequestLine().getMethod(); if (method.equalsIgnoreCase("CONNECT")) { return; } if (request.containsHeader(AUTH.WWW_AUTH_RESP)) { return; } // Obtain authentication state final AuthState authState = (AuthState) context.getAttribute( ClientContext.TARGET_AUTH_STATE); if (authState == null) { this.log.debug("Target auth state not set in the context"); return; } if (this.log.isDebugEnabled()) { this.log.debug("Target auth state: " + authState.getState()); } process(authState, request, context); } } ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/protocol/ResponseAuthCache.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/client/protocol/Resp0100644 0000000 0000000 00000014252 12301751662 032472 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseInterceptor; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthState; import org.apache.http.client.AuthCache; import org.apache.http.client.params.AuthPolicy; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.protocol.ExecutionContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Response interceptor that adds successfully completed {@link AuthScheme}s * to the local {@link AuthCache} instance. Cached {@link AuthScheme}s can be * re-used when executing requests against known hosts, thus avoiding * additional authentication round-trips. * * @since 4.1 * * @deprecated (4.2) use {@link org.apache.http.client.AuthenticationStrategy} */ @Immutable @Deprecated public class ResponseAuthCache implements HttpResponseInterceptor { private final Log log = LogFactory.getLog(getClass()); public ResponseAuthCache() { super(); } public void process(final HttpResponse response, final HttpContext context) throws HttpException, IOException { Args.notNull(response, "HTTP request"); Args.notNull(context, "HTTP context"); AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE); HttpHost target = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST); final AuthState targetState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE); if (target != null && targetState != null) { if (this.log.isDebugEnabled()) { this.log.debug("Target auth state: " + targetState.getState()); } if (isCachable(targetState)) { final SchemeRegistry schemeRegistry = (SchemeRegistry) context.getAttribute( ClientContext.SCHEME_REGISTRY); if (target.getPort() < 0) { final Scheme scheme = schemeRegistry.getScheme(target); target = new HttpHost(target.getHostName(), scheme.resolvePort(target.getPort()), target.getSchemeName()); } if (authCache == null) { authCache = new BasicAuthCache(); context.setAttribute(ClientContext.AUTH_CACHE, authCache); } switch (targetState.getState()) { case CHALLENGED: cache(authCache, target, targetState.getAuthScheme()); break; case FAILURE: uncache(authCache, target, targetState.getAuthScheme()); } } } final HttpHost proxy = (HttpHost) context.getAttribute(ExecutionContext.HTTP_PROXY_HOST); final AuthState proxyState = (AuthState) context.getAttribute(ClientContext.PROXY_AUTH_STATE); if (proxy != null && proxyState != null) { if (this.log.isDebugEnabled()) { this.log.debug("Proxy auth state: " + proxyState.getState()); } if (isCachable(proxyState)) { if (authCache == null) { authCache = new BasicAuthCache(); context.setAttribute(ClientContext.AUTH_CACHE, authCache); } switch (proxyState.getState()) { case CHALLENGED: cache(authCache, proxy, proxyState.getAuthScheme()); break; case FAILURE: uncache(authCache, proxy, proxyState.getAuthScheme()); } } } } private boolean isCachable(final AuthState authState) { final AuthScheme authScheme = authState.getAuthScheme(); if (authScheme == null || !authScheme.isComplete()) { return false; } final String schemeName = authScheme.getSchemeName(); return schemeName.equalsIgnoreCase(AuthPolicy.BASIC) || schemeName.equalsIgnoreCase(AuthPolicy.DIGEST); } private void cache(final AuthCache authCache, final HttpHost host, final AuthScheme authScheme) { if (this.log.isDebugEnabled()) { this.log.debug("Caching '" + authScheme.getSchemeName() + "' auth scheme for " + host); } authCache.put(host, authScheme); } private void uncache(final AuthCache authCache, final HttpHost host, final AuthScheme authScheme) { if (this.log.isDebugEnabled()) { this.log.debug("Removing from cache '" + authScheme.getSchemeName() + "' auth scheme for " + host); } authCache.remove(host); } } httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/0040755 0000000 0000000 00000000000 12301751662 027453 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000160 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/BasicEofSensorWatcher.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/BasicEofSensorW0100644 0000000 0000000 00000006364 12301751661 032377 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; import java.io.InputStream; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.util.Args; /** * Basic implementation of {@link EofSensorWatcher}. The underlying connection * is released on close or EOF. * * @since 4.0 * * @deprecated (4.3) do not use. */ @Deprecated @NotThreadSafe public class BasicEofSensorWatcher implements EofSensorWatcher { /** The connection to auto-release. */ protected final ManagedClientConnection managedConn; /** Whether to keep the connection alive. */ protected final boolean attemptReuse; /** * Creates a new watcher for auto-releasing a connection. * * @param conn the connection to auto-release * @param reuse whether the connection should be re-used */ public BasicEofSensorWatcher(final ManagedClientConnection conn, final boolean reuse) { Args.notNull(conn, "Connection"); managedConn = conn; attemptReuse = reuse; } public boolean eofDetected(final InputStream wrapped) throws IOException { try { if (attemptReuse) { // there may be some cleanup required, such as // reading trailers after the response body: wrapped.close(); managedConn.markReusable(); } } finally { managedConn.releaseConnection(); } return false; } public boolean streamClosed(final InputStream wrapped) throws IOException { try { if (attemptReuse) { // this assumes that closing the stream will // consume the remainder of the response body: wrapped.close(); managedConn.markReusable(); } } finally { managedConn.releaseConnection(); } return false; } public boolean streamAbort(final InputStream wrapped) throws IOException { managedConn.abortConnection(); return false; } } ././@LongLink0100644 0000000 0000000 00000000155 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/BasicManagedEntity.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/BasicManagedEnt0100644 0000000 0000000 00000014675 12301751662 032355 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.SocketException; import org.apache.http.HttpEntity; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.entity.HttpEntityWrapper; import org.apache.http.util.Args; import org.apache.http.util.EntityUtils; /** * An entity that releases a {@link ManagedClientConnection connection}. * A {@link ManagedClientConnection} will * typically not return a managed entity, but you can replace * the unmanaged entity in the response with a managed one. * * @since 4.0 * * @deprecated (4.3) do not use. */ @Deprecated @NotThreadSafe public class BasicManagedEntity extends HttpEntityWrapper implements ConnectionReleaseTrigger, EofSensorWatcher { /** The connection to release. */ protected ManagedClientConnection managedConn; /** Whether to keep the connection alive. */ protected final boolean attemptReuse; /** * Creates a new managed entity that can release a connection. * * @param entity the entity of which to wrap the content. * Note that the argument entity can no longer be used * afterwards, since the content will be taken by this * managed entity. * @param conn the connection to release * @param reuse whether the connection should be re-used */ public BasicManagedEntity(final HttpEntity entity, final ManagedClientConnection conn, final boolean reuse) { super(entity); Args.notNull(conn, "Connection"); this.managedConn = conn; this.attemptReuse = reuse; } @Override public boolean isRepeatable() { return false; } @Override public InputStream getContent() throws IOException { return new EofSensorInputStream(wrappedEntity.getContent(), this); } private void ensureConsumed() throws IOException { if (managedConn == null) { return; } try { if (attemptReuse) { // this will not trigger a callback from EofSensorInputStream EntityUtils.consume(wrappedEntity); managedConn.markReusable(); } else { managedConn.unmarkReusable(); } } finally { releaseManagedConnection(); } } /** * @deprecated (4.1) Use {@link EntityUtils#consume(HttpEntity)} */ @Deprecated @Override public void consumeContent() throws IOException { ensureConsumed(); } @Override public void writeTo(final OutputStream outstream) throws IOException { super.writeTo(outstream); ensureConsumed(); } public void releaseConnection() throws IOException { ensureConsumed(); } public void abortConnection() throws IOException { if (managedConn != null) { try { managedConn.abortConnection(); } finally { managedConn = null; } } } public boolean eofDetected(final InputStream wrapped) throws IOException { try { if (managedConn != null) { if (attemptReuse) { // there may be some cleanup required, such as // reading trailers after the response body: wrapped.close(); managedConn.markReusable(); } else { managedConn.unmarkReusable(); } } } finally { releaseManagedConnection(); } return false; } public boolean streamClosed(final InputStream wrapped) throws IOException { try { if (managedConn != null) { if (attemptReuse) { final boolean valid = managedConn.isOpen(); // this assumes that closing the stream will // consume the remainder of the response body: try { wrapped.close(); managedConn.markReusable(); } catch (final SocketException ex) { if (valid) { throw ex; } } } else { managedConn.unmarkReusable(); } } } finally { releaseManagedConnection(); } return false; } public boolean streamAbort(final InputStream wrapped) throws IOException { if (managedConn != null) { managedConn.abortConnection(); } return false; } /** * Releases the connection gracefully. * The connection attribute will be nullified. * Subsequent invocations are no-ops. * * @throws IOException in case of an IO problem. * The connection attribute will be nullified anyway. */ protected void releaseManagedConnection() throws IOException { if (managedConn != null) { try { managedConn.releaseConnection(); } finally { managedConn = null; } } } } ././@LongLink0100644 0000000 0000000 00000000171 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/ClientConnectionManagerFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/ClientConnectio0100644 0000000 0000000 00000003177 12301751661 032462 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.params.HttpParams; /** * A factory for creating new {@link ClientConnectionManager} instances. * * @since 4.0 * * @deprecated (4.3) replaced by {@link HttpClientConnectionManager}. */ @Deprecated public interface ClientConnectionManagerFactory { ClientConnectionManager newInstance( HttpParams params, SchemeRegistry schemeRegistry); } ././@LongLink0100644 0000000 0000000 00000000163 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/ClientConnectionOperator.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/ClientConnectio0100644 0000000 0000000 00000010110 12301751662 032444 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; import java.net.InetAddress; import org.apache.http.HttpHost; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; /** * ClientConnectionOperator represents a strategy for creating * {@link OperatedClientConnection} instances and updating the underlying * {@link java.net.Socket} of those objects. Implementations will most * likely make use of {@link org.apache.http.conn.scheme.SchemeSocketFactory}s * to create {@link java.net.Socket} instances. *

* The methods in this interface allow the creation of plain and layered * sockets. Creating a tunnelled connection through a proxy, however, * is not within the scope of the operator. *

* Implementations of this interface must be thread-safe. Access to shared * data must be synchronized as methods of this interface may be executed * from multiple threads. * * @since 4.0 * * @deprecated (4.3) replaced by {@link HttpClientConnectionManager}. */ @Deprecated public interface ClientConnectionOperator { /** * Creates a new connection that can be operated. * * @return a new, unopened connection for use with this operator */ OperatedClientConnection createConnection(); /** * Opens a connection to the given target host. * * @param conn the connection to open * @param target the target host to connect to * @param local the local address to route from, or * null for the default * @param context the context for the connection * @param params the parameters for the connection * * @throws IOException in case of a problem */ void openConnection(OperatedClientConnection conn, HttpHost target, InetAddress local, HttpContext context, HttpParams params) throws IOException; /** * Updates a connection with a layered secure connection. * The typical use of this method is to update a tunnelled plain * connection (HTTP) to a secure TLS/SSL connection (HTTPS). * * @param conn the open connection to update * @param target the target host for the updated connection. * The connection must already be open or tunnelled * to the host and port, but the scheme of the target * will be used to create a layered connection. * @param context the context for the connection * @param params the parameters for the updated connection * * @throws IOException in case of a problem */ void updateSecureConnection(OperatedClientConnection conn, HttpHost target, HttpContext context, HttpParams params) throws IOException; } ././@LongLink0100644 0000000 0000000 00000000166 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/MultihomePlainSocketFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/MultihomePlainS0100644 0000000 0000000 00000013763 12301751662 032457 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketTimeoutException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.apache.http.annotation.Immutable; import org.apache.http.conn.scheme.SocketFactory; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.util.Args; import org.apache.http.util.Asserts; /** * Socket factory that implements a simple multi-home fail-over on connect failure, * provided the same hostname resolves to multiple {@link InetAddress}es. Please note * the {@link #connectSocket(Socket, String, int, InetAddress, int, HttpParams)} * method cannot be reliably interrupted by closing the socket returned by the * {@link #createSocket()} method. * * @since 4.0 * * @deprecated (4.1) Do not use. For multihome support socket factories must implement * {@link org.apache.http.conn.scheme.SchemeSocketFactory} interface. */ @Deprecated @Immutable public final class MultihomePlainSocketFactory implements SocketFactory { /** * The factory singleton. */ private static final MultihomePlainSocketFactory DEFAULT_FACTORY = new MultihomePlainSocketFactory(); /** * Gets the singleton instance of this class. * @return the one and only plain socket factory */ public static MultihomePlainSocketFactory getSocketFactory() { return DEFAULT_FACTORY; } /** * Restricted default constructor. */ private MultihomePlainSocketFactory() { super(); } // non-javadoc, see interface org.apache.http.conn.SocketFactory public Socket createSocket() { return new Socket(); } /** * Attempts to connects the socket to any of the {@link InetAddress}es the * given host name resolves to. If connection to all addresses fail, the * last I/O exception is propagated to the caller. * * @param socket socket to connect to any of the given addresses * @param host Host name to connect to * @param port the port to connect to * @param localAddress local address * @param localPort local port * @param params HTTP parameters * * @throws IOException if an error occurs during the connection * @throws SocketTimeoutException if timeout expires before connecting */ public Socket connectSocket(final Socket socket, final String host, final int port, final InetAddress localAddress, final int localPort, final HttpParams params) throws IOException { Args.notNull(host, "Target host"); Args.notNull(params, "HTTP parameters"); Socket sock = socket; if (sock == null) { sock = createSocket(); } if ((localAddress != null) || (localPort > 0)) { final InetSocketAddress isa = new InetSocketAddress(localAddress, localPort > 0 ? localPort : 0); sock.bind(isa); } final int timeout = HttpConnectionParams.getConnectionTimeout(params); final InetAddress[] inetadrs = InetAddress.getAllByName(host); final List addresses = new ArrayList(inetadrs.length); addresses.addAll(Arrays.asList(inetadrs)); Collections.shuffle(addresses); IOException lastEx = null; for (final InetAddress remoteAddress: addresses) { try { sock.connect(new InetSocketAddress(remoteAddress, port), timeout); break; } catch (final SocketTimeoutException ex) { throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out"); } catch (final IOException ex) { // create new socket sock = new Socket(); // keep the last exception and retry lastEx = ex; } } if (lastEx != null) { throw lastEx; } return sock; } // connectSocket /** * Checks whether a socket connection is secure. * This factory creates plain socket connections * which are not considered secure. * * @param sock the connected socket * * @return false * * @throws IllegalArgumentException if the argument is invalid */ public final boolean isSecure(final Socket sock) throws IllegalArgumentException { Args.notNull(sock, "Socket"); // This check is performed last since it calls a method implemented // by the argument object. getClass() is final in java.lang.Object. Asserts.check(!sock.isClosed(), "Socket is closed"); return false; } // isSecure } ././@LongLink0100644 0000000 0000000 00000000163 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/OperatedClientConnection.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/OperatedClientC0100644 0000000 0000000 00000014372 12301751661 032406 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; import java.net.Socket; import org.apache.http.HttpClientConnection; import org.apache.http.HttpHost; import org.apache.http.HttpInetConnection; import org.apache.http.params.HttpParams; /** * A client-side connection that relies on outside logic to connect sockets to the * appropriate hosts. It can be operated directly by an application, or through an * {@link ClientConnectionOperator operator}. * * @since 4.0 * * @deprecated (4.3) replaced by {@link HttpClientConnectionManager}. */ @Deprecated public interface OperatedClientConnection extends HttpClientConnection, HttpInetConnection { /** * Obtains the target host for this connection. * If the connection is to a proxy but not tunnelled, this is * the proxy. If the connection is tunnelled through a proxy, * this is the target of the tunnel. *
* The return value is well-defined only while the connection is open. * It may change even while the connection is open, * because of an {@link #update update}. * * @return the host to which this connection is opened */ HttpHost getTargetHost(); /** * Indicates whether this connection is secure. * The return value is well-defined only while the connection is open. * It may change even while the connection is open, * because of an {@link #update update}. * * @return true if this connection is secure, * false otherwise */ boolean isSecure(); /** * Obtains the socket for this connection. * The return value is well-defined only while the connection is open. * It may change even while the connection is open, * because of an {@link #update update}. * * @return the socket for communicating with the * {@link #getTargetHost target host} */ Socket getSocket(); /** * Signals that this connection is in the process of being open. *

* By calling this method, the connection can be re-initialized * with a new Socket instance before {@link #openCompleted} is called. * This enabled the connection to close that socket if * {@link org.apache.http.HttpConnection#shutdown shutdown} * is called before it is fully open. Closing an unconnected socket * will interrupt a thread that is blocked on the connect. * Otherwise, that thread will either time out on the connect, * or it returns successfully and then opens this connection * which was just shut down. *

* This method can be called multiple times if the connection * is layered over another protocol. Note: This method * will not close the previously used socket. It is * the caller's responsibility to close that socket if it is * no longer required. *

* The caller must invoke {@link #openCompleted} in order to complete * the process. * * @param sock the unconnected socket which is about to * be connected. * @param target the target host of this connection */ void opening(Socket sock, HttpHost target) throws IOException; /** * Signals that the connection has been successfully open. * An attempt to call this method on an open connection will cause * an exception. * * @param secure true if this connection is secure, for * example if an SSLSocket is used, or * false if it is not secure * @param params parameters for this connection. The parameters will * be used when creating dependent objects, for example * to determine buffer sizes. */ void openCompleted(boolean secure, HttpParams params) throws IOException; /** * Updates this connection. * A connection can be updated only while it is open. * Updates are used for example when a tunnel has been established, * or when a TLS/SSL connection has been layered on top of a plain * socket connection. *
* Note: Updating the connection will not close the * previously used socket. It is the caller's responsibility to close * that socket if it is no longer required. * * @param sock the new socket for communicating with the target host, * or null to continue using the old socket. * If null is passed, helper objects that * depend on the socket should be re-used. In that case, * some changes in the parameters will not take effect. * @param target the new target host of this connection * @param secure true if this connection is now secure, * false if it is not secure * @param params new parameters for this connection */ void update(Socket sock, HttpHost target, boolean secure, HttpParams params) throws IOException; } httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/0040755 0000000 0000000 00000000000 12301751661 030735 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000171 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/ConnConnectionParamBean.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/ConnConn0100644 0000000 0000000 00000004141 12301751661 032370 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.params; import org.apache.http.params.HttpAbstractParamBean; import org.apache.http.params.HttpParams; /** * This is a Java Bean class that can be used to wrap an instance of * {@link HttpParams} and manipulate HTTP client connection parameters * using Java Beans conventions. * * @since 4.0 * * @deprecated (4.1) use custom {@link * org.apache.http.impl.conn.DefaultHttpResponseParser} implementation. */ @Deprecated public class ConnConnectionParamBean extends HttpAbstractParamBean { public ConnConnectionParamBean (final HttpParams params) { super(params); } /** * @deprecated (4.2) Use custom {@link * org.apache.http.impl.conn.DefaultHttpResponseParser} implementation */ @Deprecated public void setMaxStatusLineGarbage (final int maxStatusLineGarbage) { params.setIntParameter(ConnConnectionPNames.MAX_STATUS_LINE_GARBAGE, maxStatusLineGarbage); } } ././@LongLink0100644 0000000 0000000 00000000166 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/ConnManagerParamBean.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/ConnMana0100644 0000000 0000000 00000004410 12301751661 032346 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.params; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.params.HttpAbstractParamBean; import org.apache.http.params.HttpParams; /** * This is a Java Bean class that can be used to wrap an instance of * {@link HttpParams} and manipulate connection manager parameters * using Java Beans conventions. * * @since 4.0 * * @deprecated (4.1) use configuration methods of the specific connection manager implementation. */ @NotThreadSafe @Deprecated public class ConnManagerParamBean extends HttpAbstractParamBean { public ConnManagerParamBean (final HttpParams params) { super(params); } public void setTimeout (final long timeout) { params.setLongParameter(ConnManagerPNames.TIMEOUT, timeout); } public void setMaxTotalConnections (final int maxConnections) { params.setIntParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, maxConnections); } public void setConnectionsPerRoute(final ConnPerRouteBean connPerRoute) { params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, connPerRoute); } } ././@LongLink0100644 0000000 0000000 00000000163 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/ConnManagerParams.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/ConnMana0100644 0000000 0000000 00000012356 12301751661 032356 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.params; import org.apache.http.annotation.Immutable; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.params.HttpParams; import org.apache.http.util.Args; /** * An adaptor for manipulating HTTP connection management * parameters in {@link HttpParams}. * * @since 4.0 * * @see ConnManagerPNames * * @deprecated (4.1) use configuration methods of the specific connection manager implementation. */ @Deprecated @Immutable public final class ConnManagerParams implements ConnManagerPNames { /** The default maximum number of connections allowed overall */ public static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 20; /** * Returns the timeout in milliseconds used when retrieving a * {@link org.apache.http.conn.ManagedClientConnection} from the * {@link org.apache.http.conn.ClientConnectionManager}. * * @return timeout in milliseconds. * * @deprecated (4.1) use {@link * org.apache.http.params.HttpConnectionParams#getConnectionTimeout(HttpParams)} */ @Deprecated public static long getTimeout(final HttpParams params) { Args.notNull(params, "HTTP parameters"); return params.getLongParameter(TIMEOUT, 0); } /** * Sets the timeout in milliseconds used when retrieving a * {@link org.apache.http.conn.ManagedClientConnection} from the * {@link org.apache.http.conn.ClientConnectionManager}. * * @param timeout the timeout in milliseconds * * @deprecated (4.1) use {@link * org.apache.http.params.HttpConnectionParams#setConnectionTimeout(HttpParams, int)} */ @Deprecated public static void setTimeout(final HttpParams params, final long timeout) { Args.notNull(params, "HTTP parameters"); params.setLongParameter(TIMEOUT, timeout); } /** The default maximum number of connections allowed per host */ private static final ConnPerRoute DEFAULT_CONN_PER_ROUTE = new ConnPerRoute() { public int getMaxForRoute(final HttpRoute route) { return ConnPerRouteBean.DEFAULT_MAX_CONNECTIONS_PER_ROUTE; } }; /** * Sets lookup interface for maximum number of connections allowed per route. * * @param params HTTP parameters * @param connPerRoute lookup interface for maximum number of connections allowed * per route */ public static void setMaxConnectionsPerRoute(final HttpParams params, final ConnPerRoute connPerRoute) { Args.notNull(params, "HTTP parameters"); params.setParameter(MAX_CONNECTIONS_PER_ROUTE, connPerRoute); } /** * Returns lookup interface for maximum number of connections allowed per route. * * @param params HTTP parameters * * @return lookup interface for maximum number of connections allowed per route. */ public static ConnPerRoute getMaxConnectionsPerRoute(final HttpParams params) { Args.notNull(params, "HTTP parameters"); ConnPerRoute connPerRoute = (ConnPerRoute) params.getParameter(MAX_CONNECTIONS_PER_ROUTE); if (connPerRoute == null) { connPerRoute = DEFAULT_CONN_PER_ROUTE; } return connPerRoute; } /** * Sets the maximum number of connections allowed. * * @param params HTTP parameters * @param maxTotalConnections The maximum number of connections allowed. */ public static void setMaxTotalConnections( final HttpParams params, final int maxTotalConnections) { Args.notNull(params, "HTTP parameters"); params.setIntParameter(MAX_TOTAL_CONNECTIONS, maxTotalConnections); } /** * Gets the maximum number of connections allowed. * * @param params HTTP parameters * * @return The maximum number of connections allowed. */ public static int getMaxTotalConnections( final HttpParams params) { Args.notNull(params, "HTTP parameters"); return params.getIntParameter(MAX_TOTAL_CONNECTIONS, DEFAULT_MAX_TOTAL_CONNECTIONS); } } ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/ConnPerRoute.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/ConnPerR0100644 0000000 0000000 00000003252 12301751661 032345 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.params; import org.apache.http.conn.routing.HttpRoute; /** * This interface is intended for looking up maximum number of connections * allowed for a given route. This class can be used by pooling * {@link org.apache.http.conn.ClientConnectionManager connection managers} for * a fine-grained control of connections on a per route basis. * * @since 4.0 * * @deprecated (4.3) no longer used. */ @Deprecated public interface ConnPerRoute { int getMaxForRoute(HttpRoute route); } ././@LongLink0100644 0000000 0000000 00000000162 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/ConnPerRouteBean.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/ConnPerR0100644 0000000 0000000 00000007024 12301751661 032346 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.params; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.http.annotation.ThreadSafe; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.util.Args; /** * This class maintains a map of HTTP routes to maximum number of connections allowed * for those routes. This class can be used by pooling * {@link org.apache.http.conn.ClientConnectionManager connection managers} for * a fine-grained control of connections on a per route basis. * * @since 4.0 * * @deprecated (4.2) use {@link org.apache.http.pool.ConnPoolControl} */ @Deprecated @ThreadSafe public final class ConnPerRouteBean implements ConnPerRoute { /** The default maximum number of connections allowed per host */ public static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 2; // Per RFC 2616 sec 8.1.4 private final ConcurrentHashMap maxPerHostMap; private volatile int defaultMax; public ConnPerRouteBean(final int defaultMax) { super(); this.maxPerHostMap = new ConcurrentHashMap(); setDefaultMaxPerRoute(defaultMax); } public ConnPerRouteBean() { this(DEFAULT_MAX_CONNECTIONS_PER_ROUTE); } public int getDefaultMax() { return this.defaultMax; } /** * @since 4.1 */ public int getDefaultMaxPerRoute() { return this.defaultMax; } public void setDefaultMaxPerRoute(final int max) { Args.positive(max, "Defautl max per route"); this.defaultMax = max; } public void setMaxForRoute(final HttpRoute route, final int max) { Args.notNull(route, "HTTP route"); Args.positive(max, "Max per route"); this.maxPerHostMap.put(route, Integer.valueOf(max)); } public int getMaxForRoute(final HttpRoute route) { Args.notNull(route, "HTTP route"); final Integer max = this.maxPerHostMap.get(route); if (max != null) { return max.intValue(); } else { return this.defaultMax; } } public void setMaxForRoutes(final Map map) { if (map == null) { return; } this.maxPerHostMap.clear(); this.maxPerHostMap.putAll(map); } @Override public String toString() { return this.maxPerHostMap.toString(); } } ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/ConnRouteParamBean.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/ConnRout0100644 0000000 0000000 00000004665 12301751661 032437 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.params; import java.net.InetAddress; import org.apache.http.HttpHost; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.params.HttpAbstractParamBean; import org.apache.http.params.HttpParams; /** * This is a Java Bean class that can be used to wrap an instance of * {@link HttpParams} and manipulate connection routing parameters * using Java Beans conventions. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.client.config.RequestConfig}. */ @Deprecated @NotThreadSafe public class ConnRouteParamBean extends HttpAbstractParamBean { public ConnRouteParamBean (final HttpParams params) { super(params); } /** @see ConnRoutePNames#DEFAULT_PROXY */ public void setDefaultProxy (final HttpHost defaultProxy) { params.setParameter(ConnRoutePNames.DEFAULT_PROXY, defaultProxy); } /** @see ConnRoutePNames#LOCAL_ADDRESS */ public void setLocalAddress (final InetAddress address) { params.setParameter(ConnRoutePNames.LOCAL_ADDRESS, address); } /** @see ConnRoutePNames#FORCED_ROUTE */ public void setForcedRoute (final HttpRoute route) { params.setParameter(ConnRoutePNames.FORCED_ROUTE, route); } } ././@LongLink0100644 0000000 0000000 00000000161 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/ConnRouteParams.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/params/ConnRout0100644 0000000 0000000 00000014564 12301751661 032436 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.params; import java.net.InetAddress; import org.apache.http.HttpHost; import org.apache.http.annotation.Immutable; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.params.HttpParams; import org.apache.http.util.Args; /** * An adaptor for manipulating HTTP routing parameters * in {@link HttpParams}. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.client.config.RequestConfig}. */ @Deprecated @Immutable public class ConnRouteParams implements ConnRoutePNames { /** * A special value indicating "no host". * This relies on a nonsense scheme name to avoid conflicts * with actual hosts. Note that this is a valid host. */ public static final HttpHost NO_HOST = new HttpHost("127.0.0.255", 0, "no-host"); // Immutable /** * A special value indicating "no route". * This is a route with {@link #NO_HOST} as the target. */ public static final HttpRoute NO_ROUTE = new HttpRoute(NO_HOST); // Immutable /** Disabled default constructor. */ private ConnRouteParams() { // no body } /** * Obtains the {@link ConnRoutePNames#DEFAULT_PROXY DEFAULT_PROXY} * parameter value. * {@link #NO_HOST} will be mapped to null, * to allow unsetting in a hierarchy. * * @param params the parameters in which to look up * * @return the default proxy set in the argument parameters, or * null if not set */ public static HttpHost getDefaultProxy(final HttpParams params) { Args.notNull(params, "Parameters"); HttpHost proxy = (HttpHost) params.getParameter(DEFAULT_PROXY); if ((proxy != null) && NO_HOST.equals(proxy)) { // value is explicitly unset proxy = null; } return proxy; } /** * Sets the {@link ConnRoutePNames#DEFAULT_PROXY DEFAULT_PROXY} * parameter value. * * @param params the parameters in which to set the value * @param proxy the value to set, may be null. * Note that {@link #NO_HOST} will be mapped to * null by {@link #getDefaultProxy}, * to allow for explicit unsetting in hierarchies. */ public static void setDefaultProxy(final HttpParams params, final HttpHost proxy) { Args.notNull(params, "Parameters"); params.setParameter(DEFAULT_PROXY, proxy); } /** * Obtains the {@link ConnRoutePNames#FORCED_ROUTE FORCED_ROUTE} * parameter value. * {@link #NO_ROUTE} will be mapped to null, * to allow unsetting in a hierarchy. * * @param params the parameters in which to look up * * @return the forced route set in the argument parameters, or * null if not set */ public static HttpRoute getForcedRoute(final HttpParams params) { Args.notNull(params, "Parameters"); HttpRoute route = (HttpRoute) params.getParameter(FORCED_ROUTE); if ((route != null) && NO_ROUTE.equals(route)) { // value is explicitly unset route = null; } return route; } /** * Sets the {@link ConnRoutePNames#FORCED_ROUTE FORCED_ROUTE} * parameter value. * * @param params the parameters in which to set the value * @param route the value to set, may be null. * Note that {@link #NO_ROUTE} will be mapped to * null by {@link #getForcedRoute}, * to allow for explicit unsetting in hierarchies. */ public static void setForcedRoute(final HttpParams params, final HttpRoute route) { Args.notNull(params, "Parameters"); params.setParameter(FORCED_ROUTE, route); } /** * Obtains the {@link ConnRoutePNames#LOCAL_ADDRESS LOCAL_ADDRESS} * parameter value. * There is no special value that would automatically be mapped to * null. You can use the wildcard address (0.0.0.0 for IPv4, * :: for IPv6) to override a specific local address in a hierarchy. * * @param params the parameters in which to look up * * @return the local address set in the argument parameters, or * null if not set */ public static InetAddress getLocalAddress(final HttpParams params) { Args.notNull(params, "Parameters"); final InetAddress local = (InetAddress) params.getParameter(LOCAL_ADDRESS); // no explicit unsetting return local; } /** * Sets the {@link ConnRoutePNames#LOCAL_ADDRESS LOCAL_ADDRESS} * parameter value. * * @param params the parameters in which to set the value * @param local the value to set, may be null */ public static void setLocalAddress(final HttpParams params, final InetAddress local) { Args.notNull(params, "Parameters"); params.setParameter(LOCAL_ADDRESS, local); } } httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/scheme/0040755 0000000 0000000 00000000000 12301751661 030716 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000162 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/scheme/HostNameResolver.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/scheme/HostName0100644 0000000 0000000 00000003167 12301751661 032363 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.scheme; import java.io.IOException; import java.net.InetAddress; /** * Hostname to IP address resolver. * * @since 4.0 * * @deprecated (4.1) Do not use */ @Deprecated public interface HostNameResolver { /** * Resolves given hostname to its IP address * * @param hostname the hostname. * @return IP address. * @throws IOException */ InetAddress resolve (String hostname) throws IOException; } ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/scheme/PlainSocketFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/scheme/PlainSoc0100644 0000000 0000000 00000012416 12301751661 032352 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.scheme; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import org.apache.http.annotation.Immutable; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.util.Args; /** * The default class for creating plain (unencrypted) sockets. * * @since 4.0 * * @deprecated (4.3) use {@link org.apache.http.conn.socket.PlainConnectionSocketFactory} */ @Immutable @Deprecated public class PlainSocketFactory implements SocketFactory, SchemeSocketFactory { private final HostNameResolver nameResolver; /** * Gets the default factory. * * @return the default factory */ public static PlainSocketFactory getSocketFactory() { return new PlainSocketFactory(); } /** * @deprecated (4.1) use {@link org.apache.http.conn.DnsResolver} */ @Deprecated public PlainSocketFactory(final HostNameResolver nameResolver) { super(); this.nameResolver = nameResolver; } public PlainSocketFactory() { super(); this.nameResolver = null; } /** * @param params Optional parameters. Parameters passed to this method will have no effect. * This method will create a unconnected instance of {@link Socket} class * using default constructor. * * @since 4.1 */ public Socket createSocket(final HttpParams params) { return new Socket(); } public Socket createSocket() { return new Socket(); } /** * @since 4.1 */ public Socket connectSocket( final Socket socket, final InetSocketAddress remoteAddress, final InetSocketAddress localAddress, final HttpParams params) throws IOException, ConnectTimeoutException { Args.notNull(remoteAddress, "Remote address"); Args.notNull(params, "HTTP parameters"); Socket sock = socket; if (sock == null) { sock = createSocket(); } if (localAddress != null) { sock.setReuseAddress(HttpConnectionParams.getSoReuseaddr(params)); sock.bind(localAddress); } final int connTimeout = HttpConnectionParams.getConnectionTimeout(params); final int soTimeout = HttpConnectionParams.getSoTimeout(params); try { sock.setSoTimeout(soTimeout); sock.connect(remoteAddress, connTimeout); } catch (final SocketTimeoutException ex) { throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out"); } return sock; } /** * Checks whether a socket connection is secure. * This factory creates plain socket connections * which are not considered secure. * * @param sock the connected socket * * @return false */ public final boolean isSecure(final Socket sock) { return false; } /** * @deprecated (4.1) Use {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams)} */ @Deprecated public Socket connectSocket( final Socket socket, final String host, final int port, final InetAddress localAddress, final int localPort, final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { InetSocketAddress local = null; if (localAddress != null || localPort > 0) { local = new InetSocketAddress(localAddress, localPort > 0 ? localPort : 0); } final InetAddress remoteAddress; if (this.nameResolver != null) { remoteAddress = this.nameResolver.resolve(host); } else { remoteAddress = InetAddress.getByName(host); } final InetSocketAddress remote = new InetSocketAddress(remoteAddress, port); return connectSocket(socket, remote, local, params); } } httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/ssl/0040755 0000000 0000000 00000000000 12301751661 030253 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000157 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/ssl/SSLSocketFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/conn/ssl/SSLSocketFa0100644 0000000 0000000 00000052651 12301751661 032265 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.UnrecoverableKeyException; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import org.apache.http.HttpHost; import org.apache.http.annotation.ThreadSafe; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.HttpInetSocketAddress; import org.apache.http.conn.scheme.HostNameResolver; import org.apache.http.conn.scheme.LayeredSchemeSocketFactory; import org.apache.http.conn.scheme.LayeredSocketFactory; import org.apache.http.conn.scheme.SchemeLayeredSocketFactory; import org.apache.http.conn.socket.LayeredConnectionSocketFactory; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.Asserts; import org.apache.http.util.TextUtils; /** * Layered socket factory for TLS/SSL connections. *

* SSLSocketFactory can be used to validate the identity of the HTTPS server against a list of * trusted certificates and to authenticate to the HTTPS server using a private key. *

* SSLSocketFactory will enable server authentication when supplied with * a {@link KeyStore trust-store} file containing one or several trusted certificates. The client * secure socket will reject the connection during the SSL session handshake if the target HTTPS * server attempts to authenticate itself with a non-trusted certificate. *

* Use JDK keytool utility to import a trusted certificate and generate a trust-store file: *

 *     keytool -import -alias "my server cert" -file server.crt -keystore my.truststore
 *    
*

* In special cases the standard trust verification process can be bypassed by using a custom * {@link TrustStrategy}. This interface is primarily intended for allowing self-signed * certificates to be accepted as trusted without having to add them to the trust-store file. *

* SSLSocketFactory will enable client authentication when supplied with * a {@link KeyStore key-store} file containing a private key/public certificate * pair. The client secure socket will use the private key to authenticate * itself to the target HTTPS server during the SSL session handshake if * requested to do so by the server. * The target HTTPS server will in its turn verify the certificate presented * by the client in order to establish client's authenticity. *

* Use the following sequence of actions to generate a key-store file *

*
    *
  • *

    * Use JDK keytool utility to generate a new key *

    keytool -genkey -v -alias "my client key" -validity 365 -keystore my.keystore
    * For simplicity use the same password for the key as that of the key-store *

    *
  • *
  • *

    * Issue a certificate signing request (CSR) *

    keytool -certreq -alias "my client key" -file mycertreq.csr -keystore my.keystore
    *

    *
  • *
  • *

    * Send the certificate request to the trusted Certificate Authority for signature. * One may choose to act as her own CA and sign the certificate request using a PKI * tool, such as OpenSSL. *

    *
  • *
  • *

    * Import the trusted CA root certificate *

    keytool -import -alias "my trusted ca" -file caroot.crt -keystore my.keystore
    *

    *
  • *
  • *

    * Import the PKCS#7 file containg the complete certificate chain *

    keytool -import -alias "my client key" -file mycert.p7 -keystore my.keystore
    *

    *
  • *
  • *

    * Verify the content the resultant keystore file *

    keytool -list -v -keystore my.keystore
    *

    *
  • *
* * @since 4.0 * * @deprecated (4.3) use {@link SSLConnectionSocketFactory}. */ @ThreadSafe @Deprecated public class SSLSocketFactory implements LayeredConnectionSocketFactory, SchemeLayeredSocketFactory, LayeredSchemeSocketFactory, LayeredSocketFactory { public static final String TLS = "TLS"; public static final String SSL = "SSL"; public static final String SSLV2 = "SSLv2"; public static final X509HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER = new AllowAllHostnameVerifier(); public static final X509HostnameVerifier BROWSER_COMPATIBLE_HOSTNAME_VERIFIER = new BrowserCompatHostnameVerifier(); public static final X509HostnameVerifier STRICT_HOSTNAME_VERIFIER = new StrictHostnameVerifier(); /** * Obtains default SSL socket factory with an SSL context based on the standard JSSE * trust material (cacerts file in the security properties directory). * System properties are not taken into consideration. * * @return default SSL socket factory */ public static SSLSocketFactory getSocketFactory() throws SSLInitializationException { return new SSLSocketFactory( SSLContexts.createDefault(), BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); } private static String[] split(final String s) { if (TextUtils.isBlank(s)) { return null; } return s.split(" *, *"); } /** * Obtains default SSL socket factory with an SSL context based on system properties * as described in * * "JavaTM Secure Socket Extension (JSSE) Reference Guide for the JavaTM 2 Platform * Standard Edition 5 * * @return default system SSL socket factory */ public static SSLSocketFactory getSystemSocketFactory() throws SSLInitializationException { return new SSLSocketFactory( (javax.net.ssl.SSLSocketFactory) javax.net.ssl.SSLSocketFactory.getDefault(), split(System.getProperty("https.protocols")), split(System.getProperty("https.cipherSuites")), BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); } private final javax.net.ssl.SSLSocketFactory socketfactory; private final HostNameResolver nameResolver; // TODO: make final private volatile X509HostnameVerifier hostnameVerifier; private final String[] supportedProtocols; private final String[] supportedCipherSuites; public SSLSocketFactory( final String algorithm, final KeyStore keystore, final String keyPassword, final KeyStore truststore, final SecureRandom random, final HostNameResolver nameResolver) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { this(SSLContexts.custom() .useProtocol(algorithm) .setSecureRandom(random) .loadKeyMaterial(keystore, keyPassword != null ? keyPassword.toCharArray() : null) .loadTrustMaterial(truststore) .build(), nameResolver); } /** * @since 4.1 */ public SSLSocketFactory( final String algorithm, final KeyStore keystore, final String keyPassword, final KeyStore truststore, final SecureRandom random, final TrustStrategy trustStrategy, final X509HostnameVerifier hostnameVerifier) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { this(SSLContexts.custom() .useProtocol(algorithm) .setSecureRandom(random) .loadKeyMaterial(keystore, keyPassword != null ? keyPassword.toCharArray() : null) .loadTrustMaterial(truststore, trustStrategy) .build(), hostnameVerifier); } /** * @since 4.1 */ public SSLSocketFactory( final String algorithm, final KeyStore keystore, final String keyPassword, final KeyStore truststore, final SecureRandom random, final X509HostnameVerifier hostnameVerifier) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { this(SSLContexts.custom() .useProtocol(algorithm) .setSecureRandom(random) .loadKeyMaterial(keystore, keyPassword != null ? keyPassword.toCharArray() : null) .loadTrustMaterial(truststore) .build(), hostnameVerifier); } public SSLSocketFactory( final KeyStore keystore, final String keystorePassword, final KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { this(SSLContexts.custom() .loadKeyMaterial(keystore, keystorePassword != null ? keystorePassword.toCharArray() : null) .loadTrustMaterial(truststore) .build(), BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); } public SSLSocketFactory( final KeyStore keystore, final String keystorePassword) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException{ this(SSLContexts.custom() .loadKeyMaterial(keystore, keystorePassword != null ? keystorePassword.toCharArray() : null) .build(), BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); } public SSLSocketFactory( final KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { this(SSLContexts.custom() .loadTrustMaterial(truststore) .build(), BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); } /** * @since 4.1 */ public SSLSocketFactory( final TrustStrategy trustStrategy, final X509HostnameVerifier hostnameVerifier) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { this(SSLContexts.custom() .loadTrustMaterial(null, trustStrategy) .build(), hostnameVerifier); } /** * @since 4.1 */ public SSLSocketFactory( final TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { this(SSLContexts.custom() .loadTrustMaterial(null, trustStrategy) .build(), BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); } public SSLSocketFactory(final SSLContext sslContext) { this(sslContext, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); } public SSLSocketFactory( final SSLContext sslContext, final HostNameResolver nameResolver) { super(); this.socketfactory = sslContext.getSocketFactory(); this.hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; this.nameResolver = nameResolver; this.supportedProtocols = null; this.supportedCipherSuites = null; } /** * @since 4.1 */ public SSLSocketFactory( final SSLContext sslContext, final X509HostnameVerifier hostnameVerifier) { this(Args.notNull(sslContext, "SSL context").getSocketFactory(), null, null, hostnameVerifier); } /** * @since 4.3 */ public SSLSocketFactory( final SSLContext sslContext, final String[] supportedProtocols, final String[] supportedCipherSuites, final X509HostnameVerifier hostnameVerifier) { this(Args.notNull(sslContext, "SSL context").getSocketFactory(), supportedProtocols, supportedCipherSuites, hostnameVerifier); } /** * @since 4.2 */ public SSLSocketFactory( final javax.net.ssl.SSLSocketFactory socketfactory, final X509HostnameVerifier hostnameVerifier) { this(socketfactory, null, null, hostnameVerifier); } /** * @since 4.3 */ public SSLSocketFactory( final javax.net.ssl.SSLSocketFactory socketfactory, final String[] supportedProtocols, final String[] supportedCipherSuites, final X509HostnameVerifier hostnameVerifier) { this.socketfactory = Args.notNull(socketfactory, "SSL socket factory"); this.supportedProtocols = supportedProtocols; this.supportedCipherSuites = supportedCipherSuites; this.hostnameVerifier = hostnameVerifier != null ? hostnameVerifier : BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; this.nameResolver = null; } /** * @param params Optional parameters. Parameters passed to this method will have no effect. * This method will create a unconnected instance of {@link Socket} class. * @since 4.1 */ public Socket createSocket(final HttpParams params) throws IOException { return createSocket((HttpContext) null); } public Socket createSocket() throws IOException { return createSocket((HttpContext) null); } /** * @since 4.1 */ public Socket connectSocket( final Socket socket, final InetSocketAddress remoteAddress, final InetSocketAddress localAddress, final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { Args.notNull(remoteAddress, "Remote address"); Args.notNull(params, "HTTP parameters"); final HttpHost host; if (remoteAddress instanceof HttpInetSocketAddress) { host = ((HttpInetSocketAddress) remoteAddress).getHttpHost(); } else { host = new HttpHost(remoteAddress.getHostName(), remoteAddress.getPort(), "https"); } final int connectTimeout = HttpConnectionParams.getConnectionTimeout(params); return connectSocket(connectTimeout, socket, host, remoteAddress, localAddress, null); } /** * Checks whether a socket connection is secure. * This factory creates TLS/SSL socket connections * which, by default, are considered secure. *
* Derived classes may override this method to perform * runtime checks, for example based on the cypher suite. * * @param sock the connected socket * * @return true * * @throws IllegalArgumentException if the argument is invalid */ public boolean isSecure(final Socket sock) throws IllegalArgumentException { Args.notNull(sock, "Socket"); Asserts.check(sock instanceof SSLSocket, "Socket not created by this factory"); Asserts.check(!sock.isClosed(), "Socket is closed"); return true; } /** * @since 4.2 */ public Socket createLayeredSocket( final Socket socket, final String host, final int port, final HttpParams params) throws IOException, UnknownHostException { return createLayeredSocket(socket, host, port, (HttpContext) null); } public Socket createLayeredSocket( final Socket socket, final String host, final int port, final boolean autoClose) throws IOException, UnknownHostException { return createLayeredSocket(socket, host, port, (HttpContext) null); } public void setHostnameVerifier(final X509HostnameVerifier hostnameVerifier) { Args.notNull(hostnameVerifier, "Hostname verifier"); this.hostnameVerifier = hostnameVerifier; } public X509HostnameVerifier getHostnameVerifier() { return this.hostnameVerifier; } public Socket connectSocket( final Socket socket, final String host, final int port, final InetAddress local, final int localPort, final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { final InetAddress remote; if (this.nameResolver != null) { remote = this.nameResolver.resolve(host); } else { remote = InetAddress.getByName(host); } InetSocketAddress localAddress = null; if (local != null || localPort > 0) { localAddress = new InetSocketAddress(local, localPort > 0 ? localPort : 0); } final InetSocketAddress remoteAddress = new HttpInetSocketAddress( new HttpHost(host, port), remote, port); return connectSocket(socket, remoteAddress, localAddress, params); } public Socket createSocket( final Socket socket, final String host, final int port, final boolean autoClose) throws IOException, UnknownHostException { return createLayeredSocket(socket, host, port, autoClose); } /** * Performs any custom initialization for a newly created SSLSocket * (before the SSL handshake happens). * * The default implementation is a no-op, but could be overridden to, e.g., * call {@link SSLSocket#setEnabledCipherSuites(java.lang.String[])}. * * @since 4.2 */ protected void prepareSocket(final SSLSocket socket) throws IOException { } private void internalPrepareSocket(final SSLSocket socket) throws IOException { if (supportedProtocols != null) { socket.setEnabledProtocols(supportedProtocols); } if (supportedCipherSuites != null) { socket.setEnabledCipherSuites(supportedCipherSuites); } prepareSocket(socket); } public Socket createSocket(final HttpContext context) throws IOException { final SSLSocket sock = (SSLSocket) this.socketfactory.createSocket(); internalPrepareSocket(sock); return sock; } public Socket connectSocket( final int connectTimeout, final Socket socket, final HttpHost host, final InetSocketAddress remoteAddress, final InetSocketAddress localAddress, final HttpContext context) throws IOException { Args.notNull(host, "HTTP host"); Args.notNull(remoteAddress, "Remote address"); final Socket sock = socket != null ? socket : createSocket(context); if (localAddress != null) { sock.bind(localAddress); } try { sock.connect(remoteAddress, connectTimeout); } catch (final IOException ex) { try { sock.close(); } catch (final IOException ignore) { } throw ex; } // Setup SSL layering if necessary if (sock instanceof SSLSocket) { final SSLSocket sslsock = (SSLSocket) sock; sslsock.startHandshake(); verifyHostname(sslsock, host.getHostName()); return sock; } else { return createLayeredSocket(sock, host.getHostName(), remoteAddress.getPort(), context); } } public Socket createLayeredSocket( final Socket socket, final String target, final int port, final HttpContext context) throws IOException { final SSLSocket sslsock = (SSLSocket) this.socketfactory.createSocket( socket, target, port, true); internalPrepareSocket(sslsock); sslsock.startHandshake(); verifyHostname(sslsock, target); return sslsock; } private void verifyHostname(final SSLSocket sslsock, final String hostname) throws IOException { try { this.hostnameVerifier.verify(hostname, sslsock); // verifyHostName() didn't blowup - good! } catch (final IOException iox) { // close the socket before re-throwing the exception try { sslsock.close(); } catch (final Exception x) { /*ignore*/ } throw iox; } } } httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/cookie/0040755 0000000 0000000 00000000000 12301751661 027766 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/cookie/params/0040755 0000000 0000000 00000000000 12301751661 031251 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/cookie/params/CookieSpecParamBean.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/cookie/params/Cookie0100644 0000000 0000000 00000004216 12301751661 032405 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie.params; import java.util.Collection; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.params.HttpAbstractParamBean; import org.apache.http.params.HttpParams; /** * This is a Java Bean class that can be used to wrap an instance of * {@link HttpParams} and manipulate HTTP cookie parameters using Java Beans * conventions. * * @since 4.0 * * @deprecated (4.3) use constructor parameters of {@link * org.apache.http.cookie.CookieSpecProvider}s. */ @Deprecated @NotThreadSafe public class CookieSpecParamBean extends HttpAbstractParamBean { public CookieSpecParamBean (final HttpParams params) { super(params); } public void setDatePatterns (final Collection patterns) { params.setParameter(CookieSpecPNames.DATE_PATTERNS, patterns); } public void setSingleHeader (final boolean singleHeader) { params.setBooleanParameter(CookieSpecPNames.SINGLE_COOKIE_HEADER, singleHeader); } } httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/0040755 0000000 0000000 00000000000 12301751666 027463 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/auth/0040755 0000000 0000000 00000000000 12301751666 030424 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000157 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/auth/NegotiateScheme.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/auth/NegotiateS0100644 0000000 0000000 00000015516 12301751666 032416 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.Credentials; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.ietf.jgss.GSSException; import org.ietf.jgss.Oid; /** * SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) authentication * scheme. * * @since 4.1 * * @deprecated (4.2) use {@link SPNegoScheme} or {@link KerberosScheme}. */ @Deprecated public class NegotiateScheme extends GGSSchemeBase { private final Log log = LogFactory.getLog(getClass()); private static final String SPNEGO_OID = "1.3.6.1.5.5.2"; private static final String KERBEROS_OID = "1.2.840.113554.1.2.2"; private final SpnegoTokenGenerator spengoGenerator; /** * Default constructor for the Negotiate authentication scheme. * */ public NegotiateScheme(final SpnegoTokenGenerator spengoGenerator, final boolean stripPort) { super(stripPort); this.spengoGenerator = spengoGenerator; } public NegotiateScheme(final SpnegoTokenGenerator spengoGenerator) { this(spengoGenerator, false); } public NegotiateScheme() { this(null, false); } /** * Returns textual designation of the Negotiate authentication scheme. * * @return Negotiate */ public String getSchemeName() { return "Negotiate"; } @Override public Header authenticate( final Credentials credentials, final HttpRequest request) throws AuthenticationException { return authenticate(credentials, request, null); } /** * Produces Negotiate authorization Header based on token created by * processChallenge. * * @param credentials Never used be the Negotiate scheme but must be provided to * satisfy common-httpclient API. Credentials from JAAS will be used instead. * @param request The request being authenticated * * @throws AuthenticationException if authorisation string cannot * be generated due to an authentication failure * * @return an Negotiate authorisation Header */ @Override public Header authenticate( final Credentials credentials, final HttpRequest request, final HttpContext context) throws AuthenticationException { return super.authenticate(credentials, request, context); } @Override protected byte[] generateToken(final byte[] input, final String authServer) throws GSSException { /* Using the SPNEGO OID is the correct method. * Kerberos v5 works for IIS but not JBoss. Unwrapping * the initial token when using SPNEGO OID looks like what is * described here... * * http://msdn.microsoft.com/en-us/library/ms995330.aspx * * Another helpful URL... * * http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/tsec_SPNEGO_token.html * * Unfortunately SPNEGO is JRE >=1.6. */ /** Try SPNEGO by default, fall back to Kerberos later if error */ Oid negotiationOid = new Oid(SPNEGO_OID); byte[] token = input; boolean tryKerberos = false; try { token = generateGSSToken(token, negotiationOid, authServer); } catch (final GSSException ex){ // BAD MECH means we are likely to be using 1.5, fall back to Kerberos MECH. // Rethrow any other exception. if (ex.getMajor() == GSSException.BAD_MECH ){ log.debug("GSSException BAD_MECH, retry with Kerberos MECH"); tryKerberos = true; } else { throw ex; } } if (tryKerberos){ /* Kerberos v5 GSS-API mechanism defined in RFC 1964.*/ log.debug("Using Kerberos MECH " + KERBEROS_OID); negotiationOid = new Oid(KERBEROS_OID); token = generateGSSToken(token, negotiationOid, authServer); /* * IIS accepts Kerberos and SPNEGO tokens. Some other servers Jboss, Glassfish? * seem to only accept SPNEGO. Below wraps Kerberos into SPNEGO token. */ if (token != null && spengoGenerator != null) { try { token = spengoGenerator.generateSpnegoDERObject(token); } catch (final IOException ex) { log.error(ex.getMessage(), ex); } } } return token; } /** * Returns the authentication parameter with the given name, if available. * *

There are no valid parameters for Negotiate authentication so this * method always returns null.

* * @param name The name of the parameter to be returned * * @return the parameter with the given name */ public String getParameter(final String name) { Args.notNull(name, "Parameter name"); return null; } /** * The concept of an authentication realm is not supported by the Negotiate * authentication scheme. Always returns null. * * @return null */ public String getRealm() { return null; } /** * Returns true. * Negotiate authentication scheme is connection based. * * @return true. */ public boolean isConnectionBased() { return true; } } ././@LongLink0100644 0000000 0000000 00000000166 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/auth/NegotiateSchemeFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/auth/NegotiateS0100644 0000000 0000000 00000004624 12301751666 032414 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeFactory; import org.apache.http.params.HttpParams; /** * SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) authentication * scheme factory. * * @since 4.1 * * @deprecated (4.2) use {@link SPNegoSchemeFactory} or {@link KerberosSchemeFactory}. */ @Deprecated public class NegotiateSchemeFactory implements AuthSchemeFactory { private final SpnegoTokenGenerator spengoGenerator; private final boolean stripPort; public NegotiateSchemeFactory(final SpnegoTokenGenerator spengoGenerator, final boolean stripPort) { super(); this.spengoGenerator = spengoGenerator; this.stripPort = stripPort; } public NegotiateSchemeFactory(final SpnegoTokenGenerator spengoGenerator) { this(spengoGenerator, false); } public NegotiateSchemeFactory() { this(null, false); } public AuthScheme newInstance(final HttpParams params) { return new NegotiateScheme(this.spengoGenerator, this.stripPort); } public boolean isStripPort() { return stripPort; } public SpnegoTokenGenerator getSpengoGenerator() { return spengoGenerator; } } ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/auth/SpnegoTokenGenerator.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/auth/SpnegoToke0100644 0000000 0000000 00000003335 12301751666 032426 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import java.io.IOException; /** * Abstract SPNEGO token generator. Implementations should take an Kerberos ticket and transform * into a SPNEGO token. *

* Implementations of this interface are expected to be thread-safe. * * @since 4.1 * * @deprecated (4.2) subclass {@link KerberosScheme} and override * {@link KerberosScheme#generateGSSToken(byte[], org.ietf.jgss.Oid, String)} */ @Deprecated public interface SpnegoTokenGenerator { byte [] generateSpnegoDERObject(byte [] kerberosTicket) throws IOException; } httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/0040755 0000000 0000000 00000000000 12301751666 030741 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000177 12302131605 011631 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/AbstractAuthenticationHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/Abstract0100644 0000000 0000000 00000015334 12301751666 032432 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.FormattedHeader; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeRegistry; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.client.AuthenticationHandler; import org.apache.http.client.params.AuthPolicy; import org.apache.http.client.protocol.ClientContext; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Asserts; import org.apache.http.util.CharArrayBuffer; /** * Base class for {@link AuthenticationHandler} implementations. * * @since 4.0 * * @deprecated (4.2) use {@link org.apache.http.client.AuthenticationStrategy} */ @Deprecated @Immutable public abstract class AbstractAuthenticationHandler implements AuthenticationHandler { private final Log log = LogFactory.getLog(getClass()); private static final List DEFAULT_SCHEME_PRIORITY = Collections.unmodifiableList(Arrays.asList(new String[] { AuthPolicy.SPNEGO, AuthPolicy.NTLM, AuthPolicy.DIGEST, AuthPolicy.BASIC })); public AbstractAuthenticationHandler() { super(); } protected Map parseChallenges( final Header[] headers) throws MalformedChallengeException { final Map map = new HashMap(headers.length); for (final Header header : headers) { final CharArrayBuffer buffer; int pos; if (header instanceof FormattedHeader) { buffer = ((FormattedHeader) header).getBuffer(); pos = ((FormattedHeader) header).getValuePos(); } else { final String s = header.getValue(); if (s == null) { throw new MalformedChallengeException("Header value is null"); } buffer = new CharArrayBuffer(s.length()); buffer.append(s); pos = 0; } while (pos < buffer.length() && HTTP.isWhitespace(buffer.charAt(pos))) { pos++; } final int beginIndex = pos; while (pos < buffer.length() && !HTTP.isWhitespace(buffer.charAt(pos))) { pos++; } final int endIndex = pos; final String s = buffer.substring(beginIndex, endIndex); map.put(s.toLowerCase(Locale.US), header); } return map; } /** * Returns default list of auth scheme names in their order of preference. * * @return list of auth scheme names */ protected List getAuthPreferences() { return DEFAULT_SCHEME_PRIORITY; } /** * Returns default list of auth scheme names in their order of preference * based on the HTTP response and the current execution context. * * @param response HTTP response. * @param context HTTP execution context. * * @since 4.1 */ protected List getAuthPreferences( final HttpResponse response, final HttpContext context) { return getAuthPreferences(); } public AuthScheme selectScheme( final Map challenges, final HttpResponse response, final HttpContext context) throws AuthenticationException { final AuthSchemeRegistry registry = (AuthSchemeRegistry) context.getAttribute( ClientContext.AUTHSCHEME_REGISTRY); Asserts.notNull(registry, "AuthScheme registry"); Collection authPrefs = getAuthPreferences(response, context); if (authPrefs == null) { authPrefs = DEFAULT_SCHEME_PRIORITY; } if (this.log.isDebugEnabled()) { this.log.debug("Authentication schemes in the order of preference: " + authPrefs); } AuthScheme authScheme = null; for (final String id: authPrefs) { final Header challenge = challenges.get(id.toLowerCase(Locale.ENGLISH)); if (challenge != null) { if (this.log.isDebugEnabled()) { this.log.debug(id + " authentication scheme selected"); } try { authScheme = registry.getAuthScheme(id, response.getParams()); break; } catch (final IllegalStateException e) { if (this.log.isWarnEnabled()) { this.log.warn("Authentication scheme " + id + " not supported"); // Try again } } } else { if (this.log.isDebugEnabled()) { this.log.debug("Challenge for " + id + " authentication scheme not available"); // Try again } } } if (authScheme == null) { // If none selected, something is wrong throw new AuthenticationException( "Unable to respond to any of these challenges: " + challenges); } return authScheme; } } ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/AbstractHttpClient.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/Abstract0100644 0000000 0000000 00000107623 12301751666 032435 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.IOException; import java.lang.reflect.UndeclaredThrowableException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.ConnectionReuseStrategy; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.HttpResponseInterceptor; import org.apache.http.annotation.GuardedBy; import org.apache.http.annotation.ThreadSafe; import org.apache.http.auth.AuthSchemeRegistry; import org.apache.http.client.AuthenticationHandler; import org.apache.http.client.AuthenticationStrategy; import org.apache.http.client.BackoffManager; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ConnectionBackoffStrategy; import org.apache.http.client.CookieStore; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.RedirectHandler; import org.apache.http.client.RedirectStrategy; import org.apache.http.client.RequestDirector; import org.apache.http.client.UserTokenHandler; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.params.AuthPolicy; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.params.CookiePolicy; import org.apache.http.client.params.HttpClientParamConfig; import org.apache.http.client.protocol.ClientContext; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.ClientConnectionManagerFactory; import org.apache.http.conn.ConnectionKeepAliveStrategy; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.cookie.CookieSpecRegistry; import org.apache.http.impl.DefaultConnectionReuseStrategy; import org.apache.http.impl.auth.BasicSchemeFactory; import org.apache.http.impl.auth.DigestSchemeFactory; import org.apache.http.impl.auth.KerberosSchemeFactory; import org.apache.http.impl.auth.NTLMSchemeFactory; import org.apache.http.impl.auth.SPNegoSchemeFactory; import org.apache.http.impl.conn.BasicClientConnectionManager; import org.apache.http.impl.conn.DefaultHttpRoutePlanner; import org.apache.http.impl.conn.SchemeRegistryFactory; import org.apache.http.impl.cookie.BestMatchSpecFactory; import org.apache.http.impl.cookie.BrowserCompatSpecFactory; import org.apache.http.impl.cookie.IgnoreSpecFactory; import org.apache.http.impl.cookie.NetscapeDraftSpecFactory; import org.apache.http.impl.cookie.RFC2109SpecFactory; import org.apache.http.impl.cookie.RFC2965SpecFactory; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.BasicHttpProcessor; import org.apache.http.protocol.DefaultedHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpRequestExecutor; import org.apache.http.protocol.ImmutableHttpProcessor; import org.apache.http.util.Args; /** * Base class for {@link org.apache.http.client.HttpClient} implementations. * This class acts as a facade to a number of special purpose handler or * strategy implementations responsible for handling of a particular aspect * of the HTTP protocol such as redirect or authentication handling or * making decision about connection persistence and keep alive duration. * This enables the users to selectively replace default implementation * of those aspects with custom, application specific ones. This class * also provides factory methods to instantiate those objects: *

    *
  • {@link HttpRequestExecutor}
  • object used to transmit messages * over HTTP connections. The {@link #createRequestExecutor()} must be * implemented by concrete super classes to instantiate this object. *
  • {@link BasicHttpProcessor}
  • object to manage a list of protocol * interceptors and apply cross-cutting protocol logic to all incoming * and outgoing HTTP messages. The {@link #createHttpProcessor()} must be * implemented by concrete super classes to instantiate this object. *
  • {@link HttpRequestRetryHandler}
  • object used to decide whether * or not a failed HTTP request is safe to retry automatically. * The {@link #createHttpRequestRetryHandler()} must be * implemented by concrete super classes to instantiate this object. *
  • {@link ClientConnectionManager}
  • object used to manage * persistent HTTP connections. *
  • {@link ConnectionReuseStrategy}
  • object used to decide whether * or not a HTTP connection can be kept alive and re-used for subsequent * HTTP requests. The {@link #createConnectionReuseStrategy()} must be * implemented by concrete super classes to instantiate this object. *
  • {@link ConnectionKeepAliveStrategy}
  • object used to decide how * long a persistent HTTP connection can be kept alive. * The {@link #createConnectionKeepAliveStrategy()} must be * implemented by concrete super classes to instantiate this object. *
  • {@link CookieSpecRegistry}
  • object used to maintain a list of * supported cookie specifications. * The {@link #createCookieSpecRegistry()} must be implemented by concrete * super classes to instantiate this object. *
  • {@link CookieStore}
  • object used to maintain a collection of * cookies. The {@link #createCookieStore()} must be implemented by * concrete super classes to instantiate this object. *
  • {@link AuthSchemeRegistry}
  • object used to maintain a list of * supported authentication schemes. * The {@link #createAuthSchemeRegistry()} must be implemented by concrete * super classes to instantiate this object. *
  • {@link CredentialsProvider}
  • object used to maintain * a collection user credentials. The {@link #createCredentialsProvider()} * must be implemented by concrete super classes to instantiate * this object. *
  • {@link AuthenticationStrategy}
  • object used to authenticate * against the target host. * The {@link #createTargetAuthenticationStrategy()} must be implemented * by concrete super classes to instantiate this object. *
  • {@link AuthenticationStrategy}
  • object used to authenticate * against the proxy host. * The {@link #createProxyAuthenticationStrategy()} must be implemented * by concrete super classes to instantiate this object. *
  • {@link HttpRoutePlanner}
  • object used to calculate a route * for establishing a connection to the target host. The route * may involve multiple intermediate hops. * The {@link #createHttpRoutePlanner()} must be implemented * by concrete super classes to instantiate this object. *
  • {@link RedirectStrategy}
  • object used to determine if an HTTP * request should be redirected to a new location in response to an HTTP * response received from the target server. *
  • {@link UserTokenHandler}
  • object used to determine if the * execution context is user identity specific. * The {@link #createUserTokenHandler()} must be implemented by * concrete super classes to instantiate this object. *
*

* This class also maintains a list of protocol interceptors intended * for processing outgoing requests and incoming responses and provides * methods for managing those interceptors. New protocol interceptors can be * introduced to the protocol processor chain or removed from it if needed. * Internally protocol interceptors are stored in a simple * {@link java.util.ArrayList}. They are executed in the same natural order * as they are added to the list. *

* AbstractHttpClient is thread safe. It is recommended that the same * instance of this class is reused for multiple request executions. * When an instance of DefaultHttpClient is no longer needed and is about * to go out of scope the connection manager associated with it must be * shut down by calling {@link ClientConnectionManager#shutdown()}! * * @since 4.0 * * @deprecated (4.3) use {@link HttpClientBuilder}. */ @ThreadSafe @Deprecated public abstract class AbstractHttpClient extends CloseableHttpClient { private final Log log = LogFactory.getLog(getClass()); /** The parameters. */ @GuardedBy("this") private HttpParams defaultParams; /** The request executor. */ @GuardedBy("this") private HttpRequestExecutor requestExec; /** The connection manager. */ @GuardedBy("this") private ClientConnectionManager connManager; /** The connection re-use strategy. */ @GuardedBy("this") private ConnectionReuseStrategy reuseStrategy; /** The connection keep-alive strategy. */ @GuardedBy("this") private ConnectionKeepAliveStrategy keepAliveStrategy; /** The cookie spec registry. */ @GuardedBy("this") private CookieSpecRegistry supportedCookieSpecs; /** The authentication scheme registry. */ @GuardedBy("this") private AuthSchemeRegistry supportedAuthSchemes; /** The HTTP protocol processor and its immutable copy. */ @GuardedBy("this") private BasicHttpProcessor mutableProcessor; @GuardedBy("this") private ImmutableHttpProcessor protocolProcessor; /** The request retry handler. */ @GuardedBy("this") private HttpRequestRetryHandler retryHandler; /** The redirect handler. */ @GuardedBy("this") private RedirectStrategy redirectStrategy; /** The target authentication handler. */ @GuardedBy("this") private AuthenticationStrategy targetAuthStrategy; /** The proxy authentication handler. */ @GuardedBy("this") private AuthenticationStrategy proxyAuthStrategy; /** The cookie store. */ @GuardedBy("this") private CookieStore cookieStore; /** The credentials provider. */ @GuardedBy("this") private CredentialsProvider credsProvider; /** The route planner. */ @GuardedBy("this") private HttpRoutePlanner routePlanner; /** The user token handler. */ @GuardedBy("this") private UserTokenHandler userTokenHandler; /** The connection backoff strategy. */ @GuardedBy("this") private ConnectionBackoffStrategy connectionBackoffStrategy; /** The backoff manager. */ @GuardedBy("this") private BackoffManager backoffManager; /** * Creates a new HTTP client. * * @param conman the connection manager * @param params the parameters */ protected AbstractHttpClient( final ClientConnectionManager conman, final HttpParams params) { super(); defaultParams = params; connManager = conman; } // constructor protected abstract HttpParams createHttpParams(); protected abstract BasicHttpProcessor createHttpProcessor(); protected HttpContext createHttpContext() { final HttpContext context = new BasicHttpContext(); context.setAttribute( ClientContext.SCHEME_REGISTRY, getConnectionManager().getSchemeRegistry()); context.setAttribute( ClientContext.AUTHSCHEME_REGISTRY, getAuthSchemes()); context.setAttribute( ClientContext.COOKIESPEC_REGISTRY, getCookieSpecs()); context.setAttribute( ClientContext.COOKIE_STORE, getCookieStore()); context.setAttribute( ClientContext.CREDS_PROVIDER, getCredentialsProvider()); return context; } protected ClientConnectionManager createClientConnectionManager() { final SchemeRegistry registry = SchemeRegistryFactory.createDefault(); ClientConnectionManager connManager = null; final HttpParams params = getParams(); ClientConnectionManagerFactory factory = null; final String className = (String) params.getParameter( ClientPNames.CONNECTION_MANAGER_FACTORY_CLASS_NAME); if (className != null) { try { final Class clazz = Class.forName(className); factory = (ClientConnectionManagerFactory) clazz.newInstance(); } catch (final ClassNotFoundException ex) { throw new IllegalStateException("Invalid class name: " + className); } catch (final IllegalAccessException ex) { throw new IllegalAccessError(ex.getMessage()); } catch (final InstantiationException ex) { throw new InstantiationError(ex.getMessage()); } } if (factory != null) { connManager = factory.newInstance(params, registry); } else { connManager = new BasicClientConnectionManager(registry); } return connManager; } protected AuthSchemeRegistry createAuthSchemeRegistry() { final AuthSchemeRegistry registry = new AuthSchemeRegistry(); registry.register( AuthPolicy.BASIC, new BasicSchemeFactory()); registry.register( AuthPolicy.DIGEST, new DigestSchemeFactory()); registry.register( AuthPolicy.NTLM, new NTLMSchemeFactory()); registry.register( AuthPolicy.SPNEGO, new SPNegoSchemeFactory()); registry.register( AuthPolicy.KERBEROS, new KerberosSchemeFactory()); return registry; } protected CookieSpecRegistry createCookieSpecRegistry() { final CookieSpecRegistry registry = new CookieSpecRegistry(); registry.register( CookiePolicy.BEST_MATCH, new BestMatchSpecFactory()); registry.register( CookiePolicy.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory()); registry.register( CookiePolicy.NETSCAPE, new NetscapeDraftSpecFactory()); registry.register( CookiePolicy.RFC_2109, new RFC2109SpecFactory()); registry.register( CookiePolicy.RFC_2965, new RFC2965SpecFactory()); registry.register( CookiePolicy.IGNORE_COOKIES, new IgnoreSpecFactory()); return registry; } protected HttpRequestExecutor createRequestExecutor() { return new HttpRequestExecutor(); } protected ConnectionReuseStrategy createConnectionReuseStrategy() { return new DefaultConnectionReuseStrategy(); } protected ConnectionKeepAliveStrategy createConnectionKeepAliveStrategy() { return new DefaultConnectionKeepAliveStrategy(); } protected HttpRequestRetryHandler createHttpRequestRetryHandler() { return new DefaultHttpRequestRetryHandler(); } /** * @deprecated (4.1) do not use */ @Deprecated protected RedirectHandler createRedirectHandler() { return new DefaultRedirectHandler(); } protected AuthenticationStrategy createTargetAuthenticationStrategy() { return new TargetAuthenticationStrategy(); } /** * @deprecated (4.2) do not use */ @Deprecated protected AuthenticationHandler createTargetAuthenticationHandler() { return new DefaultTargetAuthenticationHandler(); } protected AuthenticationStrategy createProxyAuthenticationStrategy() { return new ProxyAuthenticationStrategy(); } /** * @deprecated (4.2) do not use */ @Deprecated protected AuthenticationHandler createProxyAuthenticationHandler() { return new DefaultProxyAuthenticationHandler(); } protected CookieStore createCookieStore() { return new BasicCookieStore(); } protected CredentialsProvider createCredentialsProvider() { return new BasicCredentialsProvider(); } protected HttpRoutePlanner createHttpRoutePlanner() { return new DefaultHttpRoutePlanner(getConnectionManager().getSchemeRegistry()); } protected UserTokenHandler createUserTokenHandler() { return new DefaultUserTokenHandler(); } // non-javadoc, see interface HttpClient public synchronized final HttpParams getParams() { if (defaultParams == null) { defaultParams = createHttpParams(); } return defaultParams; } /** * Replaces the parameters. * The implementation here does not update parameters of dependent objects. * * @param params the new default parameters */ public synchronized void setParams(final HttpParams params) { defaultParams = params; } public synchronized final ClientConnectionManager getConnectionManager() { if (connManager == null) { connManager = createClientConnectionManager(); } return connManager; } public synchronized final HttpRequestExecutor getRequestExecutor() { if (requestExec == null) { requestExec = createRequestExecutor(); } return requestExec; } public synchronized final AuthSchemeRegistry getAuthSchemes() { if (supportedAuthSchemes == null) { supportedAuthSchemes = createAuthSchemeRegistry(); } return supportedAuthSchemes; } public synchronized void setAuthSchemes(final AuthSchemeRegistry registry) { supportedAuthSchemes = registry; } public synchronized final ConnectionBackoffStrategy getConnectionBackoffStrategy() { return connectionBackoffStrategy; } public synchronized void setConnectionBackoffStrategy(final ConnectionBackoffStrategy strategy) { connectionBackoffStrategy = strategy; } public synchronized final CookieSpecRegistry getCookieSpecs() { if (supportedCookieSpecs == null) { supportedCookieSpecs = createCookieSpecRegistry(); } return supportedCookieSpecs; } public synchronized final BackoffManager getBackoffManager() { return backoffManager; } public synchronized void setBackoffManager(final BackoffManager manager) { backoffManager = manager; } public synchronized void setCookieSpecs(final CookieSpecRegistry registry) { supportedCookieSpecs = registry; } public synchronized final ConnectionReuseStrategy getConnectionReuseStrategy() { if (reuseStrategy == null) { reuseStrategy = createConnectionReuseStrategy(); } return reuseStrategy; } public synchronized void setReuseStrategy(final ConnectionReuseStrategy strategy) { this.reuseStrategy = strategy; } public synchronized final ConnectionKeepAliveStrategy getConnectionKeepAliveStrategy() { if (keepAliveStrategy == null) { keepAliveStrategy = createConnectionKeepAliveStrategy(); } return keepAliveStrategy; } public synchronized void setKeepAliveStrategy(final ConnectionKeepAliveStrategy strategy) { this.keepAliveStrategy = strategy; } public synchronized final HttpRequestRetryHandler getHttpRequestRetryHandler() { if (retryHandler == null) { retryHandler = createHttpRequestRetryHandler(); } return retryHandler; } public synchronized void setHttpRequestRetryHandler(final HttpRequestRetryHandler handler) { this.retryHandler = handler; } /** * @deprecated (4.1) do not use */ @Deprecated public synchronized final RedirectHandler getRedirectHandler() { return createRedirectHandler(); } /** * @deprecated (4.1) do not use */ @Deprecated public synchronized void setRedirectHandler(final RedirectHandler handler) { this.redirectStrategy = new DefaultRedirectStrategyAdaptor(handler); } /** * @since 4.1 */ public synchronized final RedirectStrategy getRedirectStrategy() { if (redirectStrategy == null) { redirectStrategy = new DefaultRedirectStrategy(); } return redirectStrategy; } /** * @since 4.1 */ public synchronized void setRedirectStrategy(final RedirectStrategy strategy) { this.redirectStrategy = strategy; } /** * @deprecated (4.2) do not use */ @Deprecated public synchronized final AuthenticationHandler getTargetAuthenticationHandler() { return createTargetAuthenticationHandler(); } /** * @deprecated (4.2) do not use */ @Deprecated public synchronized void setTargetAuthenticationHandler(final AuthenticationHandler handler) { this.targetAuthStrategy = new AuthenticationStrategyAdaptor(handler); } /** * @since 4.2 */ public synchronized final AuthenticationStrategy getTargetAuthenticationStrategy() { if (targetAuthStrategy == null) { targetAuthStrategy = createTargetAuthenticationStrategy(); } return targetAuthStrategy; } /** * @since 4.2 */ public synchronized void setTargetAuthenticationStrategy(final AuthenticationStrategy strategy) { this.targetAuthStrategy = strategy; } /** * @deprecated (4.2) do not use */ @Deprecated public synchronized final AuthenticationHandler getProxyAuthenticationHandler() { return createProxyAuthenticationHandler(); } /** * @deprecated (4.2) do not use */ @Deprecated public synchronized void setProxyAuthenticationHandler(final AuthenticationHandler handler) { this.proxyAuthStrategy = new AuthenticationStrategyAdaptor(handler); } /** * @since 4.2 */ public synchronized final AuthenticationStrategy getProxyAuthenticationStrategy() { if (proxyAuthStrategy == null) { proxyAuthStrategy = createProxyAuthenticationStrategy(); } return proxyAuthStrategy; } /** * @since 4.2 */ public synchronized void setProxyAuthenticationStrategy(final AuthenticationStrategy strategy) { this.proxyAuthStrategy = strategy; } public synchronized final CookieStore getCookieStore() { if (cookieStore == null) { cookieStore = createCookieStore(); } return cookieStore; } public synchronized void setCookieStore(final CookieStore cookieStore) { this.cookieStore = cookieStore; } public synchronized final CredentialsProvider getCredentialsProvider() { if (credsProvider == null) { credsProvider = createCredentialsProvider(); } return credsProvider; } public synchronized void setCredentialsProvider(final CredentialsProvider credsProvider) { this.credsProvider = credsProvider; } public synchronized final HttpRoutePlanner getRoutePlanner() { if (this.routePlanner == null) { this.routePlanner = createHttpRoutePlanner(); } return this.routePlanner; } public synchronized void setRoutePlanner(final HttpRoutePlanner routePlanner) { this.routePlanner = routePlanner; } public synchronized final UserTokenHandler getUserTokenHandler() { if (this.userTokenHandler == null) { this.userTokenHandler = createUserTokenHandler(); } return this.userTokenHandler; } public synchronized void setUserTokenHandler(final UserTokenHandler handler) { this.userTokenHandler = handler; } protected synchronized final BasicHttpProcessor getHttpProcessor() { if (mutableProcessor == null) { mutableProcessor = createHttpProcessor(); } return mutableProcessor; } private synchronized HttpProcessor getProtocolProcessor() { if (protocolProcessor == null) { // Get mutable HTTP processor final BasicHttpProcessor proc = getHttpProcessor(); // and create an immutable copy of it final int reqc = proc.getRequestInterceptorCount(); final HttpRequestInterceptor[] reqinterceptors = new HttpRequestInterceptor[reqc]; for (int i = 0; i < reqc; i++) { reqinterceptors[i] = proc.getRequestInterceptor(i); } final int resc = proc.getResponseInterceptorCount(); final HttpResponseInterceptor[] resinterceptors = new HttpResponseInterceptor[resc]; for (int i = 0; i < resc; i++) { resinterceptors[i] = proc.getResponseInterceptor(i); } protocolProcessor = new ImmutableHttpProcessor(reqinterceptors, resinterceptors); } return protocolProcessor; } public synchronized int getResponseInterceptorCount() { return getHttpProcessor().getResponseInterceptorCount(); } public synchronized HttpResponseInterceptor getResponseInterceptor(final int index) { return getHttpProcessor().getResponseInterceptor(index); } public synchronized HttpRequestInterceptor getRequestInterceptor(final int index) { return getHttpProcessor().getRequestInterceptor(index); } public synchronized int getRequestInterceptorCount() { return getHttpProcessor().getRequestInterceptorCount(); } public synchronized void addResponseInterceptor(final HttpResponseInterceptor itcp) { getHttpProcessor().addInterceptor(itcp); protocolProcessor = null; } public synchronized void addResponseInterceptor(final HttpResponseInterceptor itcp, final int index) { getHttpProcessor().addInterceptor(itcp, index); protocolProcessor = null; } public synchronized void clearResponseInterceptors() { getHttpProcessor().clearResponseInterceptors(); protocolProcessor = null; } public synchronized void removeResponseInterceptorByClass(final Class clazz) { getHttpProcessor().removeResponseInterceptorByClass(clazz); protocolProcessor = null; } public synchronized void addRequestInterceptor(final HttpRequestInterceptor itcp) { getHttpProcessor().addInterceptor(itcp); protocolProcessor = null; } public synchronized void addRequestInterceptor(final HttpRequestInterceptor itcp, final int index) { getHttpProcessor().addInterceptor(itcp, index); protocolProcessor = null; } public synchronized void clearRequestInterceptors() { getHttpProcessor().clearRequestInterceptors(); protocolProcessor = null; } public synchronized void removeRequestInterceptorByClass(final Class clazz) { getHttpProcessor().removeRequestInterceptorByClass(clazz); protocolProcessor = null; } @Override protected final CloseableHttpResponse doExecute(final HttpHost target, final HttpRequest request, final HttpContext context) throws IOException, ClientProtocolException { Args.notNull(request, "HTTP request"); // a null target may be acceptable, this depends on the route planner // a null context is acceptable, default context created below HttpContext execContext = null; RequestDirector director = null; HttpRoutePlanner routePlanner = null; ConnectionBackoffStrategy connectionBackoffStrategy = null; BackoffManager backoffManager = null; // Initialize the request execution context making copies of // all shared objects that are potentially threading unsafe. synchronized (this) { final HttpContext defaultContext = createHttpContext(); if (context == null) { execContext = defaultContext; } else { execContext = new DefaultedHttpContext(context, defaultContext); } final HttpParams params = determineParams(request); final RequestConfig config = HttpClientParamConfig.getRequestConfig(params); execContext.setAttribute(ClientContext.REQUEST_CONFIG, config); // Create a director for this request director = createClientRequestDirector( getRequestExecutor(), getConnectionManager(), getConnectionReuseStrategy(), getConnectionKeepAliveStrategy(), getRoutePlanner(), getProtocolProcessor(), getHttpRequestRetryHandler(), getRedirectStrategy(), getTargetAuthenticationStrategy(), getProxyAuthenticationStrategy(), getUserTokenHandler(), params); routePlanner = getRoutePlanner(); connectionBackoffStrategy = getConnectionBackoffStrategy(); backoffManager = getBackoffManager(); } try { if (connectionBackoffStrategy != null && backoffManager != null) { final HttpHost targetForRoute = (target != null) ? target : (HttpHost) determineParams(request).getParameter( ClientPNames.DEFAULT_HOST); final HttpRoute route = routePlanner.determineRoute(targetForRoute, request, execContext); final CloseableHttpResponse out; try { out = CloseableHttpResponseProxy.newProxy( director.execute(target, request, execContext)); } catch (final RuntimeException re) { if (connectionBackoffStrategy.shouldBackoff(re)) { backoffManager.backOff(route); } throw re; } catch (final Exception e) { if (connectionBackoffStrategy.shouldBackoff(e)) { backoffManager.backOff(route); } if (e instanceof HttpException) { throw (HttpException)e; } if (e instanceof IOException) { throw (IOException)e; } throw new UndeclaredThrowableException(e); } if (connectionBackoffStrategy.shouldBackoff(out)) { backoffManager.backOff(route); } else { backoffManager.probe(route); } return out; } else { return CloseableHttpResponseProxy.newProxy( director.execute(target, request, execContext)); } } catch(final HttpException httpException) { throw new ClientProtocolException(httpException); } } /** * @deprecated (4.1) do not use */ @Deprecated protected RequestDirector createClientRequestDirector( final HttpRequestExecutor requestExec, final ClientConnectionManager conman, final ConnectionReuseStrategy reustrat, final ConnectionKeepAliveStrategy kastrat, final HttpRoutePlanner rouplan, final HttpProcessor httpProcessor, final HttpRequestRetryHandler retryHandler, final RedirectHandler redirectHandler, final AuthenticationHandler targetAuthHandler, final AuthenticationHandler proxyAuthHandler, final UserTokenHandler userTokenHandler, final HttpParams params) { return new DefaultRequestDirector( requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler, redirectHandler, targetAuthHandler, proxyAuthHandler, userTokenHandler, params); } /** * @deprecated (4.2) do not use */ @Deprecated protected RequestDirector createClientRequestDirector( final HttpRequestExecutor requestExec, final ClientConnectionManager conman, final ConnectionReuseStrategy reustrat, final ConnectionKeepAliveStrategy kastrat, final HttpRoutePlanner rouplan, final HttpProcessor httpProcessor, final HttpRequestRetryHandler retryHandler, final RedirectStrategy redirectStrategy, final AuthenticationHandler targetAuthHandler, final AuthenticationHandler proxyAuthHandler, final UserTokenHandler userTokenHandler, final HttpParams params) { return new DefaultRequestDirector( log, requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler, redirectStrategy, targetAuthHandler, proxyAuthHandler, userTokenHandler, params); } /** * @since 4.2 */ protected RequestDirector createClientRequestDirector( final HttpRequestExecutor requestExec, final ClientConnectionManager conman, final ConnectionReuseStrategy reustrat, final ConnectionKeepAliveStrategy kastrat, final HttpRoutePlanner rouplan, final HttpProcessor httpProcessor, final HttpRequestRetryHandler retryHandler, final RedirectStrategy redirectStrategy, final AuthenticationStrategy targetAuthStrategy, final AuthenticationStrategy proxyAuthStrategy, final UserTokenHandler userTokenHandler, final HttpParams params) { return new DefaultRequestDirector( log, requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler, redirectStrategy, targetAuthStrategy, proxyAuthStrategy, userTokenHandler, params); } /** * Obtains parameters for executing a request. * The default implementation in this class creates a new * {@link ClientParamsStack} from the request parameters * and the client parameters. *
* This method is called by the default implementation of * {@link #execute(HttpHost,HttpRequest,HttpContext)} * to obtain the parameters for the * {@link DefaultRequestDirector}. * * @param req the request that will be executed * * @return the parameters to use */ protected HttpParams determineParams(final HttpRequest req) { return new ClientParamsStack (null, getParams(), req.getParams(), null); } public void close() { getConnectionManager().shutdown(); } } ././@LongLink0100644 0000000 0000000 00000000177 12302131605 011631 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/AuthenticationStrategyAdaptor.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/Authenti0100644 0000000 0000000 00000014541 12301751666 032447 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.LinkedList; import java.util.Locale; import java.util.Map; import java.util.Queue; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthOption; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.Credentials; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.client.AuthCache; import org.apache.http.client.AuthenticationHandler; import org.apache.http.client.AuthenticationStrategy; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.params.AuthPolicy; import org.apache.http.client.protocol.ClientContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * @deprecated (4.2) do not use */ @Immutable @Deprecated class AuthenticationStrategyAdaptor implements AuthenticationStrategy { private final Log log = LogFactory.getLog(getClass()); private final AuthenticationHandler handler; public AuthenticationStrategyAdaptor(final AuthenticationHandler handler) { super(); this.handler = handler; } public boolean isAuthenticationRequested( final HttpHost authhost, final HttpResponse response, final HttpContext context) { return this.handler.isAuthenticationRequested(response, context); } public Map getChallenges( final HttpHost authhost, final HttpResponse response, final HttpContext context) throws MalformedChallengeException { return this.handler.getChallenges(response, context); } public Queue select( final Map challenges, final HttpHost authhost, final HttpResponse response, final HttpContext context) throws MalformedChallengeException { Args.notNull(challenges, "Map of auth challenges"); Args.notNull(authhost, "Host"); Args.notNull(response, "HTTP response"); Args.notNull(context, "HTTP context"); final Queue options = new LinkedList(); final CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute( ClientContext.CREDS_PROVIDER); if (credsProvider == null) { this.log.debug("Credentials provider not set in the context"); return options; } final AuthScheme authScheme; try { authScheme = this.handler.selectScheme(challenges, response, context); } catch (final AuthenticationException ex) { if (this.log.isWarnEnabled()) { this.log.warn(ex.getMessage(), ex); } return options; } final String id = authScheme.getSchemeName(); final Header challenge = challenges.get(id.toLowerCase(Locale.US)); authScheme.processChallenge(challenge); final AuthScope authScope = new AuthScope( authhost.getHostName(), authhost.getPort(), authScheme.getRealm(), authScheme.getSchemeName()); final Credentials credentials = credsProvider.getCredentials(authScope); if (credentials != null) { options.add(new AuthOption(authScheme, credentials)); } return options; } public void authSucceeded( final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) { AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE); if (isCachable(authScheme)) { if (authCache == null) { authCache = new BasicAuthCache(); context.setAttribute(ClientContext.AUTH_CACHE, authCache); } if (this.log.isDebugEnabled()) { this.log.debug("Caching '" + authScheme.getSchemeName() + "' auth scheme for " + authhost); } authCache.put(authhost, authScheme); } } public void authFailed( final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) { final AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE); if (authCache == null) { return; } if (this.log.isDebugEnabled()) { this.log.debug("Removing from cache '" + authScheme.getSchemeName() + "' auth scheme for " + authhost); } authCache.remove(authhost); } private boolean isCachable(final AuthScheme authScheme) { if (authScheme == null || !authScheme.isComplete()) { return false; } final String schemeName = authScheme.getSchemeName(); return schemeName.equalsIgnoreCase(AuthPolicy.BASIC) || schemeName.equalsIgnoreCase(AuthPolicy.DIGEST); } public AuthenticationHandler getHandler() { return this.handler; } } ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/AutoRetryHttpClient.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/AutoRetr0100644 0000000 0000000 00000016077 12301751666 032441 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.IOException; import java.io.InterruptedIOException; import java.net.URI; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.ServiceUnavailableRetryStrategy; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.EntityUtils; /** * {@link HttpClient} implementation that can automatically retry the request in case of * a non-2xx response using the {@link ServiceUnavailableRetryStrategy} interface. * * @since 4.2 * * @deprecated (4.3) use {@link HttpClientBuilder}. */ @Deprecated @ThreadSafe public class AutoRetryHttpClient implements HttpClient { private final HttpClient backend; private final ServiceUnavailableRetryStrategy retryStrategy; private final Log log = LogFactory.getLog(getClass()); public AutoRetryHttpClient( final HttpClient client, final ServiceUnavailableRetryStrategy retryStrategy) { super(); Args.notNull(client, "HttpClient"); Args.notNull(retryStrategy, "ServiceUnavailableRetryStrategy"); this.backend = client; this.retryStrategy = retryStrategy; } /** * Constructs a {@code AutoRetryHttpClient} with default caching settings that * stores cache entries in memory and uses a vanilla * {@link DefaultHttpClient} for backend requests. */ public AutoRetryHttpClient() { this(new DefaultHttpClient(), new DefaultServiceUnavailableRetryStrategy()); } /** * Constructs a {@code AutoRetryHttpClient} with the given caching options that * stores cache entries in memory and uses a vanilla * {@link DefaultHttpClient} for backend requests. * * @param config * retry configuration module options */ public AutoRetryHttpClient(final ServiceUnavailableRetryStrategy config) { this(new DefaultHttpClient(), config); } /** * Constructs a {@code AutoRetryHttpClient} with default caching settings that * stores cache entries in memory and uses the given {@link HttpClient} for * backend requests. * * @param client * used to make origin requests */ public AutoRetryHttpClient(final HttpClient client) { this(client, new DefaultServiceUnavailableRetryStrategy()); } public HttpResponse execute(final HttpHost target, final HttpRequest request) throws IOException { final HttpContext defaultContext = null; return execute(target, request, defaultContext); } public T execute(final HttpHost target, final HttpRequest request, final ResponseHandler responseHandler) throws IOException { return execute(target, request, responseHandler, null); } public T execute(final HttpHost target, final HttpRequest request, final ResponseHandler responseHandler, final HttpContext context) throws IOException { final HttpResponse resp = execute(target, request, context); return responseHandler.handleResponse(resp); } public HttpResponse execute(final HttpUriRequest request) throws IOException { final HttpContext context = null; return execute(request, context); } public HttpResponse execute(final HttpUriRequest request, final HttpContext context) throws IOException { final URI uri = request.getURI(); final HttpHost httpHost = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme()); return execute(httpHost, request, context); } public T execute(final HttpUriRequest request, final ResponseHandler responseHandler) throws IOException { return execute(request, responseHandler, null); } public T execute(final HttpUriRequest request, final ResponseHandler responseHandler, final HttpContext context) throws IOException { final HttpResponse resp = execute(request, context); return responseHandler.handleResponse(resp); } public HttpResponse execute(final HttpHost target, final HttpRequest request, final HttpContext context) throws IOException { for (int c = 1;; c++) { final HttpResponse response = backend.execute(target, request, context); try { if (retryStrategy.retryRequest(response, c, context)) { EntityUtils.consume(response.getEntity()); final long nextInterval = retryStrategy.getRetryInterval(); try { log.trace("Wait for " + nextInterval); Thread.sleep(nextInterval); } catch (final InterruptedException e) { Thread.currentThread().interrupt(); throw new InterruptedIOException(); } } else { return response; } } catch (final RuntimeException ex) { try { EntityUtils.consume(response.getEntity()); } catch (final IOException ioex) { log.warn("I/O error consuming response content", ioex); } throw ex; } } } public ClientConnectionManager getConnectionManager() { return backend.getConnectionManager(); } public HttpParams getParams() { return backend.getParams(); } } ././@LongLink0100644 0000000 0000000 00000000163 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/ClientParamsStack.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/ClientPa0100644 0000000 0000000 00000022353 12301751666 032365 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.params.AbstractHttpParams; import org.apache.http.params.HttpParams; import org.apache.http.util.Args; /** * Represents a stack of parameter collections. * When retrieving a parameter, the stack is searched in a fixed order * and the first match returned. Setting parameters via the stack is * not supported. To minimize overhead, the stack has a fixed size and * does not maintain an internal array. * The supported stack entries, sorted by increasing priority, are: *

    *
  1. Application parameters: * expected to be the same for all clients used by an application. * These provide "global", that is application-wide, defaults. *
  2. *
  3. Client parameters: * specific to an instance of * {@link org.apache.http.client.HttpClient HttpClient}. * These provide client specific defaults. *
  4. *
  5. Request parameters: * specific to a single request execution. * For overriding client and global defaults. *
  6. *
  7. Override parameters: * specific to an instance of * {@link org.apache.http.client.HttpClient HttpClient}. * These can be used to set parameters that cannot be overridden * on a per-request basis. *
  8. *
* Each stack entry may be null. That is preferable over * an empty params collection, since it avoids searching the empty collection * when looking up parameters. * * @since 4.0 * * @deprecated (4.3) use configuration classes provided 'org.apache.http.config' * and 'org.apache.http.client.config' */ @NotThreadSafe @Deprecated public class ClientParamsStack extends AbstractHttpParams { /** The application parameter collection, or null. */ protected final HttpParams applicationParams; /** The client parameter collection, or null. */ protected final HttpParams clientParams; /** The request parameter collection, or null. */ protected final HttpParams requestParams; /** The override parameter collection, or null. */ protected final HttpParams overrideParams; /** * Creates a new parameter stack from elements. * The arguments will be stored as-is, there is no copying to * prevent modification. * * @param aparams application parameters, or null * @param cparams client parameters, or null * @param rparams request parameters, or null * @param oparams override parameters, or null */ public ClientParamsStack(final HttpParams aparams, final HttpParams cparams, final HttpParams rparams, final HttpParams oparams) { applicationParams = aparams; clientParams = cparams; requestParams = rparams; overrideParams = oparams; } /** * Creates a copy of a parameter stack. * The new stack will have the exact same entries as the argument stack. * There is no copying of parameters. * * @param stack the stack to copy */ public ClientParamsStack(final ClientParamsStack stack) { this(stack.getApplicationParams(), stack.getClientParams(), stack.getRequestParams(), stack.getOverrideParams()); } /** * Creates a modified copy of a parameter stack. * The new stack will contain the explicitly passed elements. * For elements where the explicit argument is null, * the corresponding element from the argument stack is used. * There is no copying of parameters. * * @param stack the stack to modify * @param aparams application parameters, or null * @param cparams client parameters, or null * @param rparams request parameters, or null * @param oparams override parameters, or null */ public ClientParamsStack(final ClientParamsStack stack, final HttpParams aparams, final HttpParams cparams, final HttpParams rparams, final HttpParams oparams) { this((aparams != null) ? aparams : stack.getApplicationParams(), (cparams != null) ? cparams : stack.getClientParams(), (rparams != null) ? rparams : stack.getRequestParams(), (oparams != null) ? oparams : stack.getOverrideParams()); } /** * Obtains the application parameters of this stack. * * @return the application parameters, or null */ public final HttpParams getApplicationParams() { return applicationParams; } /** * Obtains the client parameters of this stack. * * @return the client parameters, or null */ public final HttpParams getClientParams() { return clientParams; } /** * Obtains the request parameters of this stack. * * @return the request parameters, or null */ public final HttpParams getRequestParams() { return requestParams; } /** * Obtains the override parameters of this stack. * * @return the override parameters, or null */ public final HttpParams getOverrideParams() { return overrideParams; } /** * Obtains a parameter from this stack. * See class comment for search order. * * @param name the name of the parameter to obtain * * @return the highest-priority value for that parameter, or * null if it is not set anywhere in this stack */ public Object getParameter(final String name) { Args.notNull(name, "Parameter name"); Object result = null; if (overrideParams != null) { result = overrideParams.getParameter(name); } if ((result == null) && (requestParams != null)) { result = requestParams.getParameter(name); } if ((result == null) && (clientParams != null)) { result = clientParams.getParameter(name); } if ((result == null) && (applicationParams != null)) { result = applicationParams.getParameter(name); } return result; } /** * Does not set a parameter. * Parameter stacks are read-only. It is possible, though discouraged, * to access and modify specific stack entries. * Derived classes may change this behavior. * * @param name ignored * @param value ignored * * @return nothing * * @throws UnsupportedOperationException always */ public HttpParams setParameter(final String name, final Object value) throws UnsupportedOperationException { throw new UnsupportedOperationException ("Setting parameters in a stack is not supported."); } /** * Does not remove a parameter. * Parameter stacks are read-only. It is possible, though discouraged, * to access and modify specific stack entries. * Derived classes may change this behavior. * * @param name ignored * * @return nothing * * @throws UnsupportedOperationException always */ public boolean removeParameter(final String name) { throw new UnsupportedOperationException ("Removing parameters in a stack is not supported."); } /** * Does not copy parameters. * Parameter stacks are lightweight objects, expected to be instantiated * as needed and to be used only in a very specific context. On top of * that, they are read-only. The typical copy operation to prevent * accidental modification of parameters passed by the application to * a framework object is therefore pointless and disabled. * Create a new stack if you really need a copy. *
* Derived classes may change this behavior. * * @return this parameter stack */ public HttpParams copy() { return this; } } ././@LongLink0100644 0000000 0000000 00000000173 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/ContentEncodingHttpClient.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/ContentE0100644 0000000 0000000 00000006354 12301751666 032410 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.protocol.RequestAcceptEncoding; import org.apache.http.client.protocol.ResponseContentEncoding; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpProcessor; /** * {@link DefaultHttpClient} sub-class which includes a {@link RequestAcceptEncoding} * for the request and response. * * Deprecation note: due to the way this class modifies a response body * without changing the response headers to reflect the entity changes, it cannot * be used as the "backend" for a caching {@link * org.apache.http.client.HttpClient} and still have uncompressed responses be cached. * Users are encouraged to use the {@link DecompressingHttpClient} instead * of this class, which can be wired in either before or after caching, depending on * whether you want to cache responses in compressed or uncompressed form. * * @since 4.1 * * @deprecated (4.2) use {@link HttpClientBuilder} */ @Deprecated @ThreadSafe // since DefaultHttpClient is public class ContentEncodingHttpClient extends DefaultHttpClient { /** * Creates a new HTTP client from parameters and a connection manager. * * @param params the parameters * @param conman the connection manager */ public ContentEncodingHttpClient(final ClientConnectionManager conman, final HttpParams params) { super(conman, params); } /** * @param params */ public ContentEncodingHttpClient(final HttpParams params) { this(null, params); } /** * */ public ContentEncodingHttpClient() { this(null); } /** * {@inheritDoc} */ @Override protected BasicHttpProcessor createHttpProcessor() { final BasicHttpProcessor result = super.createHttpProcessor(); result.addRequestInterceptor(new RequestAcceptEncoding()); result.addResponseInterceptor(new ResponseContentEncoding()); return result; } } ././@LongLink0100644 0000000 0000000 00000000171 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/DecompressingHttpClient.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/Decompre0100644 0000000 0000000 00000020753 12301751666 032426 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.IOException; import java.net.URI; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseInterceptor; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.protocol.RequestAcceptEncoding; import org.apache.http.client.protocol.ResponseContentEncoding; import org.apache.http.client.utils.URIUtils; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; /** *

Decorator adding support for compressed responses. This class sets * the Accept-Encoding header on requests to indicate * support for the gzip and deflate * compression schemes; it then checks the Content-Encoding * header on the response to uncompress any compressed response bodies. * The {@link java.io.InputStream} of the entity will contain the uncompressed * content.

* *

N.B. Any upstream clients of this class need to be aware that * this effectively obscures visibility into the length of a server * response body, since the Content-Length header will * correspond to the compressed entity length received from the server, * but the content length experienced by reading the response body may * be different (hopefully higher!).

* *

That said, this decorator is compatible with the * CachingHttpClient in that the two decorators can be added * in either order and still have cacheable responses be cached.

* * @since 4.2 * * @deprecated (4.3) use {@link HttpClientBuilder} */ @Deprecated public class DecompressingHttpClient implements HttpClient { private final HttpClient backend; private final HttpRequestInterceptor acceptEncodingInterceptor; private final HttpResponseInterceptor contentEncodingInterceptor; /** * Constructs a decorator to ask for and handle compressed * entities on the fly. */ public DecompressingHttpClient() { this(new DefaultHttpClient()); } /** * Constructs a decorator to ask for and handle compressed * entities on the fly. * @param backend the {@link HttpClient} to use for actually * issuing requests */ public DecompressingHttpClient(final HttpClient backend) { this(backend, new RequestAcceptEncoding(), new ResponseContentEncoding()); } DecompressingHttpClient(final HttpClient backend, final HttpRequestInterceptor requestInterceptor, final HttpResponseInterceptor responseInterceptor) { this.backend = backend; this.acceptEncodingInterceptor = requestInterceptor; this.contentEncodingInterceptor = responseInterceptor; } public HttpParams getParams() { return backend.getParams(); } public ClientConnectionManager getConnectionManager() { return backend.getConnectionManager(); } public HttpResponse execute(final HttpUriRequest request) throws IOException, ClientProtocolException { return execute(getHttpHost(request), request, (HttpContext)null); } /** * Gets the HttpClient to issue request. * * @return the HttpClient to issue request */ public HttpClient getHttpClient() { return this.backend; } HttpHost getHttpHost(final HttpUriRequest request) { final URI uri = request.getURI(); return URIUtils.extractHost(uri); } public HttpResponse execute(final HttpUriRequest request, final HttpContext context) throws IOException, ClientProtocolException { return execute(getHttpHost(request), request, context); } public HttpResponse execute(final HttpHost target, final HttpRequest request) throws IOException, ClientProtocolException { return execute(target, request, (HttpContext)null); } public HttpResponse execute(final HttpHost target, final HttpRequest request, final HttpContext context) throws IOException, ClientProtocolException { try { final HttpContext localContext = context != null ? context : new BasicHttpContext(); final HttpRequest wrapped; if (request instanceof HttpEntityEnclosingRequest) { wrapped = new EntityEnclosingRequestWrapper((HttpEntityEnclosingRequest) request); } else { wrapped = new RequestWrapper(request); } acceptEncodingInterceptor.process(wrapped, localContext); final HttpResponse response = backend.execute(target, wrapped, localContext); try { contentEncodingInterceptor.process(response, localContext); if (Boolean.TRUE.equals(localContext.getAttribute(ResponseContentEncoding.UNCOMPRESSED))) { response.removeHeaders("Content-Length"); response.removeHeaders("Content-Encoding"); response.removeHeaders("Content-MD5"); } return response; } catch (final HttpException ex) { EntityUtils.consume(response.getEntity()); throw ex; } catch (final IOException ex) { EntityUtils.consume(response.getEntity()); throw ex; } catch (final RuntimeException ex) { EntityUtils.consume(response.getEntity()); throw ex; } } catch (final HttpException e) { throw new ClientProtocolException(e); } } public T execute(final HttpUriRequest request, final ResponseHandler responseHandler) throws IOException, ClientProtocolException { return execute(getHttpHost(request), request, responseHandler); } public T execute(final HttpUriRequest request, final ResponseHandler responseHandler, final HttpContext context) throws IOException, ClientProtocolException { return execute(getHttpHost(request), request, responseHandler, context); } public T execute(final HttpHost target, final HttpRequest request, final ResponseHandler responseHandler) throws IOException, ClientProtocolException { return execute(target, request, responseHandler, null); } public T execute(final HttpHost target, final HttpRequest request, final ResponseHandler responseHandler, final HttpContext context) throws IOException, ClientProtocolException { final HttpResponse response = execute(target, request, context); try { return responseHandler.handleResponse(response); } finally { final HttpEntity entity = response.getEntity(); if (entity != null) { EntityUtils.consume(entity); } } } } ././@LongLink0100644 0000000 0000000 00000000163 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/DefaultHttpClient.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/DefaultH0100644 0000000 0000000 00000023032 12301751666 032355 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.HttpVersion; import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.protocol.RequestAddCookies; import org.apache.http.client.protocol.RequestAuthCache; import org.apache.http.client.protocol.RequestClientConnControl; import org.apache.http.client.protocol.RequestDefaultHeaders; import org.apache.http.client.protocol.RequestProxyAuthentication; import org.apache.http.client.protocol.RequestTargetAuthentication; import org.apache.http.client.protocol.ResponseProcessCookies; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.params.SyncBasicHttpParams; import org.apache.http.protocol.BasicHttpProcessor; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.RequestContent; import org.apache.http.protocol.RequestExpectContinue; import org.apache.http.protocol.RequestTargetHost; import org.apache.http.protocol.RequestUserAgent; /** * Default implementation of {@link org.apache.http.client.HttpClient} pre-configured * for most common use scenarios. *

* Please see the Javadoc for {@link #createHttpProcessor()} for the details of the interceptors * that are set up by default. *

* Additional interceptors can be added as follows, but * take care not to add the same interceptor more than once. *

 * DefaultHttpClient httpclient = new DefaultHttpClient();
 * httpclient.addRequestInterceptor(new RequestAcceptEncoding());
 * httpclient.addResponseInterceptor(new ResponseContentEncoding());
 * 
*

* This class sets up the following parameters if not explicitly set: *

    *
  • Version: HttpVersion.HTTP_1_1
  • *
  • ContentCharset: HTTP.DEFAULT_CONTENT_CHARSET
  • *
  • NoTcpDelay: true
  • *
  • SocketBufferSize: 8192
  • *
  • UserAgent: Apache-HttpClient/release (java 1.5)
  • *
*

* The following parameters can be used to customize the behavior of this * class: *

    *
  • {@link org.apache.http.params.CoreProtocolPNames#PROTOCOL_VERSION}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#USE_EXPECT_CONTINUE}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#WAIT_FOR_CONTINUE}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#USER_AGENT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_REUSEADDR}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#STALE_CONNECTION_CHECK}
  • *
  • {@link org.apache.http.conn.params.ConnRoutePNames#FORCED_ROUTE}
  • *
  • {@link org.apache.http.conn.params.ConnRoutePNames#LOCAL_ADDRESS}
  • *
  • {@link org.apache.http.conn.params.ConnRoutePNames#DEFAULT_PROXY}
  • *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#DATE_PATTERNS}
  • *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#SINGLE_COOKIE_HEADER}
  • *
  • {@link org.apache.http.auth.params.AuthPNames#CREDENTIAL_CHARSET}
  • *
  • {@link org.apache.http.client.params.ClientPNames#COOKIE_POLICY}
  • *
  • {@link org.apache.http.client.params.ClientPNames#HANDLE_AUTHENTICATION}
  • *
  • {@link org.apache.http.client.params.ClientPNames#HANDLE_REDIRECTS}
  • *
  • {@link org.apache.http.client.params.ClientPNames#MAX_REDIRECTS}
  • *
  • {@link org.apache.http.client.params.ClientPNames#ALLOW_CIRCULAR_REDIRECTS}
  • *
  • {@link org.apache.http.client.params.ClientPNames#VIRTUAL_HOST}
  • *
  • {@link org.apache.http.client.params.ClientPNames#DEFAULT_HOST}
  • *
  • {@link org.apache.http.client.params.ClientPNames#DEFAULT_HEADERS}
  • *
  • {@link org.apache.http.client.params.ClientPNames#CONN_MANAGER_TIMEOUT}
  • *
* * @since 4.0 * * @deprecated (4.3) use {@link HttpClientBuilder}. */ @ThreadSafe @Deprecated public class DefaultHttpClient extends AbstractHttpClient { /** * Creates a new HTTP client from parameters and a connection manager. * * @param params the parameters * @param conman the connection manager */ public DefaultHttpClient( final ClientConnectionManager conman, final HttpParams params) { super(conman, params); } /** * @since 4.1 */ public DefaultHttpClient( final ClientConnectionManager conman) { super(conman, null); } public DefaultHttpClient(final HttpParams params) { super(null, params); } public DefaultHttpClient() { super(null, null); } /** * Creates the default set of HttpParams by invoking {@link DefaultHttpClient#setDefaultHttpParams(HttpParams)} * * @return a new instance of {@link SyncBasicHttpParams} with the defaults applied to it. */ @Override protected HttpParams createHttpParams() { final HttpParams params = new SyncBasicHttpParams(); setDefaultHttpParams(params); return params; } /** * Saves the default set of HttpParams in the provided parameter. * These are: *
    *
  • {@link org.apache.http.params.CoreProtocolPNames#PROTOCOL_VERSION}: * 1.1
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#HTTP_CONTENT_CHARSET}: * ISO-8859-1
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}: * true
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}: * 8192
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#USER_AGENT}: * Apache-HttpClient/ (java 1.5)
  • *
*/ public static void setDefaultHttpParams(final HttpParams params) { HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, HTTP.DEF_CONTENT_CHARSET.name()); HttpConnectionParams.setTcpNoDelay(params, true); HttpConnectionParams.setSocketBufferSize(params, 8192); HttpProtocolParams.setUserAgent(params, HttpClientBuilder.DEFAULT_USER_AGENT); } /** * Create the processor with the following interceptors: *
    *
  • {@link RequestDefaultHeaders}
  • *
  • {@link RequestContent}
  • *
  • {@link RequestTargetHost}
  • *
  • {@link RequestClientConnControl}
  • *
  • {@link RequestUserAgent}
  • *
  • {@link RequestExpectContinue}
  • *
  • {@link RequestAddCookies}
  • *
  • {@link ResponseProcessCookies}
  • *
  • {@link RequestAuthCache}
  • *
  • {@link RequestTargetAuthentication}
  • *
  • {@link RequestProxyAuthentication}
  • *
*

* @return the processor with the added interceptors. */ @Override protected BasicHttpProcessor createHttpProcessor() { final BasicHttpProcessor httpproc = new BasicHttpProcessor(); httpproc.addInterceptor(new RequestDefaultHeaders()); // Required protocol interceptors httpproc.addInterceptor(new RequestContent()); httpproc.addInterceptor(new RequestTargetHost()); // Recommended protocol interceptors httpproc.addInterceptor(new RequestClientConnControl()); httpproc.addInterceptor(new RequestUserAgent()); httpproc.addInterceptor(new RequestExpectContinue()); // HTTP state management interceptors httpproc.addInterceptor(new RequestAddCookies()); httpproc.addInterceptor(new ResponseProcessCookies()); // HTTP authentication interceptors httpproc.addInterceptor(new RequestAuthCache()); httpproc.addInterceptor(new RequestTargetAuthentication()); httpproc.addInterceptor(new RequestProxyAuthentication()); return httpproc; } } ././@LongLink0100644 0000000 0000000 00000000203 12302131605 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/DefaultProxyAuthenticationHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/DefaultP0100644 0000000 0000000 00000006130 12301751666 032365 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.List; import java.util.Map; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AUTH; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.auth.params.AuthPNames; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Default {@link org.apache.http.client.AuthenticationHandler} implementation * for proxy host authentication. * * @since 4.0 * * @deprecated (4.2) use {@link ProxyAuthenticationStrategy} */ @Deprecated @Immutable public class DefaultProxyAuthenticationHandler extends AbstractAuthenticationHandler { public DefaultProxyAuthenticationHandler() { super(); } public boolean isAuthenticationRequested( final HttpResponse response, final HttpContext context) { Args.notNull(response, "HTTP response"); final int status = response.getStatusLine().getStatusCode(); return status == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED; } public Map getChallenges( final HttpResponse response, final HttpContext context) throws MalformedChallengeException { Args.notNull(response, "HTTP response"); final Header[] headers = response.getHeaders(AUTH.PROXY_AUTH); return parseChallenges(headers); } @Override protected List getAuthPreferences( final HttpResponse response, final HttpContext context) { @SuppressWarnings("unchecked") final List authpref = (List) response.getParams().getParameter( AuthPNames.PROXY_AUTH_PREF); if (authpref != null) { return authpref; } else { return super.getAuthPreferences(response, context); } } } ././@LongLink0100644 0000000 0000000 00000000170 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/DefaultRedirectHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/DefaultR0100644 0000000 0000000 00000015432 12301751666 032374 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.net.URI; import java.net.URISyntaxException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.ProtocolException; import org.apache.http.annotation.Immutable; import org.apache.http.client.CircularRedirectException; import org.apache.http.client.RedirectHandler; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.utils.URIUtils; import org.apache.http.params.HttpParams; import org.apache.http.protocol.ExecutionContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.Asserts; /** * Default implementation of {@link RedirectHandler}. * * @since 4.0 * * @deprecated (4.1) use {@link DefaultRedirectStrategy}. */ @Immutable @Deprecated public class DefaultRedirectHandler implements RedirectHandler { private final Log log = LogFactory.getLog(getClass()); private static final String REDIRECT_LOCATIONS = "http.protocol.redirect-locations"; public DefaultRedirectHandler() { super(); } public boolean isRedirectRequested( final HttpResponse response, final HttpContext context) { Args.notNull(response, "HTTP response"); final int statusCode = response.getStatusLine().getStatusCode(); switch (statusCode) { case HttpStatus.SC_MOVED_TEMPORARILY: case HttpStatus.SC_MOVED_PERMANENTLY: case HttpStatus.SC_TEMPORARY_REDIRECT: final HttpRequest request = (HttpRequest) context.getAttribute( ExecutionContext.HTTP_REQUEST); final String method = request.getRequestLine().getMethod(); return method.equalsIgnoreCase(HttpGet.METHOD_NAME) || method.equalsIgnoreCase(HttpHead.METHOD_NAME); case HttpStatus.SC_SEE_OTHER: return true; default: return false; } //end of switch } public URI getLocationURI( final HttpResponse response, final HttpContext context) throws ProtocolException { Args.notNull(response, "HTTP response"); //get the location header to find out where to redirect to final Header locationHeader = response.getFirstHeader("location"); if (locationHeader == null) { // got a redirect response, but no location header throw new ProtocolException( "Received redirect response " + response.getStatusLine() + " but no location header"); } final String location = locationHeader.getValue(); if (this.log.isDebugEnabled()) { this.log.debug("Redirect requested to location '" + location + "'"); } URI uri; try { uri = new URI(location); } catch (final URISyntaxException ex) { throw new ProtocolException("Invalid redirect URI: " + location, ex); } final HttpParams params = response.getParams(); // rfc2616 demands the location value be a complete URI // Location = "Location" ":" absoluteURI if (!uri.isAbsolute()) { if (params.isParameterTrue(ClientPNames.REJECT_RELATIVE_REDIRECT)) { throw new ProtocolException("Relative redirect location '" + uri + "' not allowed"); } // Adjust location URI final HttpHost target = (HttpHost) context.getAttribute( ExecutionContext.HTTP_TARGET_HOST); Asserts.notNull(target, "Target host"); final HttpRequest request = (HttpRequest) context.getAttribute( ExecutionContext.HTTP_REQUEST); try { final URI requestURI = new URI(request.getRequestLine().getUri()); final URI absoluteRequestURI = URIUtils.rewriteURI(requestURI, target, true); uri = URIUtils.resolve(absoluteRequestURI, uri); } catch (final URISyntaxException ex) { throw new ProtocolException(ex.getMessage(), ex); } } if (params.isParameterFalse(ClientPNames.ALLOW_CIRCULAR_REDIRECTS)) { RedirectLocations redirectLocations = (RedirectLocations) context.getAttribute( REDIRECT_LOCATIONS); if (redirectLocations == null) { redirectLocations = new RedirectLocations(); context.setAttribute(REDIRECT_LOCATIONS, redirectLocations); } final URI redirectURI; if (uri.getFragment() != null) { try { final HttpHost target = new HttpHost( uri.getHost(), uri.getPort(), uri.getScheme()); redirectURI = URIUtils.rewriteURI(uri, target, true); } catch (final URISyntaxException ex) { throw new ProtocolException(ex.getMessage(), ex); } } else { redirectURI = uri; } if (redirectLocations.contains(redirectURI)) { throw new CircularRedirectException("Circular redirect to '" + redirectURI + "'"); } else { redirectLocations.add(redirectURI); } } return uri; } } ././@LongLink0100644 0000000 0000000 00000000200 12302131605 011614 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/DefaultRedirectStrategyAdaptor.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/DefaultR0100644 0000000 0000000 00000005416 12301751666 032375 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.net.URI; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.ProtocolException; import org.apache.http.annotation.Immutable; import org.apache.http.client.RedirectHandler; import org.apache.http.client.RedirectStrategy; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.protocol.HttpContext; /** * @deprecated (4.1) do not use */ @Immutable @Deprecated class DefaultRedirectStrategyAdaptor implements RedirectStrategy { private final RedirectHandler handler; public DefaultRedirectStrategyAdaptor(final RedirectHandler handler) { super(); this.handler = handler; } public boolean isRedirected( final HttpRequest request, final HttpResponse response, final HttpContext context) throws ProtocolException { return this.handler.isRedirectRequested(response, context); } public HttpUriRequest getRedirect( final HttpRequest request, final HttpResponse response, final HttpContext context) throws ProtocolException { final URI uri = this.handler.getLocationURI(response, context); final String method = request.getRequestLine().getMethod(); if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) { return new HttpHead(uri); } else { return new HttpGet(uri); } } public RedirectHandler getHandler() { return this.handler; } } ././@LongLink0100644 0000000 0000000 00000000170 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/DefaultRequestDirector.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/DefaultR0100644 0000000 0000000 00000136314 12301751666 032377 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.IOException; import java.io.InterruptedIOException; import java.net.URI; import java.net.URISyntaxException; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.ConnectionReuseStrategy; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.NoHttpResponseException; import org.apache.http.ProtocolException; import org.apache.http.ProtocolVersion; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AuthProtocolState; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthState; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthenticationHandler; import org.apache.http.client.AuthenticationStrategy; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.NonRepeatableRequestException; import org.apache.http.client.RedirectException; import org.apache.http.client.RedirectHandler; import org.apache.http.client.RedirectStrategy; import org.apache.http.client.RequestDirector; import org.apache.http.client.UserTokenHandler; import org.apache.http.client.methods.AbortableHttpRequest; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.params.HttpClientParams; import org.apache.http.client.protocol.ClientContext; import org.apache.http.client.utils.URIUtils; import org.apache.http.conn.BasicManagedEntity; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.ClientConnectionRequest; import org.apache.http.conn.ConnectionKeepAliveStrategy; import org.apache.http.conn.ManagedClientConnection; import org.apache.http.conn.routing.BasicRouteDirector; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.HttpRouteDirector; import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.conn.scheme.Scheme; import org.apache.http.entity.BufferedHttpEntity; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.conn.ConnectionShutdownException; import org.apache.http.message.BasicHttpRequest; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.ExecutionContext; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpRequestExecutor; import org.apache.http.util.Args; import org.apache.http.util.EntityUtils; /** * Default implementation of {@link RequestDirector}. *

* The following parameters can be used to customize the behavior of this * class: *

    *
  • {@link org.apache.http.params.CoreProtocolPNames#PROTOCOL_VERSION}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#USE_EXPECT_CONTINUE}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#WAIT_FOR_CONTINUE}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#USER_AGENT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_REUSEADDR}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#STALE_CONNECTION_CHECK}
  • *
  • {@link org.apache.http.conn.params.ConnRoutePNames#FORCED_ROUTE}
  • *
  • {@link org.apache.http.conn.params.ConnRoutePNames#LOCAL_ADDRESS}
  • *
  • {@link org.apache.http.conn.params.ConnRoutePNames#DEFAULT_PROXY}
  • *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#DATE_PATTERNS}
  • *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#SINGLE_COOKIE_HEADER}
  • *
  • {@link org.apache.http.auth.params.AuthPNames#CREDENTIAL_CHARSET}
  • *
  • {@link org.apache.http.client.params.ClientPNames#COOKIE_POLICY}
  • *
  • {@link org.apache.http.client.params.ClientPNames#HANDLE_AUTHENTICATION}
  • *
  • {@link org.apache.http.client.params.ClientPNames#HANDLE_REDIRECTS}
  • *
  • {@link org.apache.http.client.params.ClientPNames#MAX_REDIRECTS}
  • *
  • {@link org.apache.http.client.params.ClientPNames#ALLOW_CIRCULAR_REDIRECTS}
  • *
  • {@link org.apache.http.client.params.ClientPNames#VIRTUAL_HOST}
  • *
  • {@link org.apache.http.client.params.ClientPNames#DEFAULT_HOST}
  • *
  • {@link org.apache.http.client.params.ClientPNames#DEFAULT_HEADERS}
  • *
  • {@link org.apache.http.client.params.ClientPNames#CONN_MANAGER_TIMEOUT}
  • *
* * @since 4.0 * * @deprecated (4.3) */ @Deprecated @NotThreadSafe // e.g. managedConn public class DefaultRequestDirector implements RequestDirector { private final Log log; /** The connection manager. */ protected final ClientConnectionManager connManager; /** The route planner. */ protected final HttpRoutePlanner routePlanner; /** The connection re-use strategy. */ protected final ConnectionReuseStrategy reuseStrategy; /** The keep-alive duration strategy. */ protected final ConnectionKeepAliveStrategy keepAliveStrategy; /** The request executor. */ protected final HttpRequestExecutor requestExec; /** The HTTP protocol processor. */ protected final HttpProcessor httpProcessor; /** The request retry handler. */ protected final HttpRequestRetryHandler retryHandler; /** The redirect handler. */ @Deprecated protected final RedirectHandler redirectHandler; /** The redirect strategy. */ protected final RedirectStrategy redirectStrategy; /** The target authentication handler. */ @Deprecated protected final AuthenticationHandler targetAuthHandler; /** The target authentication handler. */ protected final AuthenticationStrategy targetAuthStrategy; /** The proxy authentication handler. */ @Deprecated protected final AuthenticationHandler proxyAuthHandler; /** The proxy authentication handler. */ protected final AuthenticationStrategy proxyAuthStrategy; /** The user token handler. */ protected final UserTokenHandler userTokenHandler; /** The HTTP parameters. */ protected final HttpParams params; /** The currently allocated connection. */ protected ManagedClientConnection managedConn; protected final AuthState targetAuthState; protected final AuthState proxyAuthState; private final HttpAuthenticator authenticator; private int execCount; private int redirectCount; private final int maxRedirects; private HttpHost virtualHost; @Deprecated public DefaultRequestDirector( final HttpRequestExecutor requestExec, final ClientConnectionManager conman, final ConnectionReuseStrategy reustrat, final ConnectionKeepAliveStrategy kastrat, final HttpRoutePlanner rouplan, final HttpProcessor httpProcessor, final HttpRequestRetryHandler retryHandler, final RedirectHandler redirectHandler, final AuthenticationHandler targetAuthHandler, final AuthenticationHandler proxyAuthHandler, final UserTokenHandler userTokenHandler, final HttpParams params) { this(LogFactory.getLog(DefaultRequestDirector.class), requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler, new DefaultRedirectStrategyAdaptor(redirectHandler), new AuthenticationStrategyAdaptor(targetAuthHandler), new AuthenticationStrategyAdaptor(proxyAuthHandler), userTokenHandler, params); } @Deprecated public DefaultRequestDirector( final Log log, final HttpRequestExecutor requestExec, final ClientConnectionManager conman, final ConnectionReuseStrategy reustrat, final ConnectionKeepAliveStrategy kastrat, final HttpRoutePlanner rouplan, final HttpProcessor httpProcessor, final HttpRequestRetryHandler retryHandler, final RedirectStrategy redirectStrategy, final AuthenticationHandler targetAuthHandler, final AuthenticationHandler proxyAuthHandler, final UserTokenHandler userTokenHandler, final HttpParams params) { this(LogFactory.getLog(DefaultRequestDirector.class), requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler, redirectStrategy, new AuthenticationStrategyAdaptor(targetAuthHandler), new AuthenticationStrategyAdaptor(proxyAuthHandler), userTokenHandler, params); } /** * @since 4.2 */ public DefaultRequestDirector( final Log log, final HttpRequestExecutor requestExec, final ClientConnectionManager conman, final ConnectionReuseStrategy reustrat, final ConnectionKeepAliveStrategy kastrat, final HttpRoutePlanner rouplan, final HttpProcessor httpProcessor, final HttpRequestRetryHandler retryHandler, final RedirectStrategy redirectStrategy, final AuthenticationStrategy targetAuthStrategy, final AuthenticationStrategy proxyAuthStrategy, final UserTokenHandler userTokenHandler, final HttpParams params) { Args.notNull(log, "Log"); Args.notNull(requestExec, "Request executor"); Args.notNull(conman, "Client connection manager"); Args.notNull(reustrat, "Connection reuse strategy"); Args.notNull(kastrat, "Connection keep alive strategy"); Args.notNull(rouplan, "Route planner"); Args.notNull(httpProcessor, "HTTP protocol processor"); Args.notNull(retryHandler, "HTTP request retry handler"); Args.notNull(redirectStrategy, "Redirect strategy"); Args.notNull(targetAuthStrategy, "Target authentication strategy"); Args.notNull(proxyAuthStrategy, "Proxy authentication strategy"); Args.notNull(userTokenHandler, "User token handler"); Args.notNull(params, "HTTP parameters"); this.log = log; this.authenticator = new HttpAuthenticator(log); this.requestExec = requestExec; this.connManager = conman; this.reuseStrategy = reustrat; this.keepAliveStrategy = kastrat; this.routePlanner = rouplan; this.httpProcessor = httpProcessor; this.retryHandler = retryHandler; this.redirectStrategy = redirectStrategy; this.targetAuthStrategy = targetAuthStrategy; this.proxyAuthStrategy = proxyAuthStrategy; this.userTokenHandler = userTokenHandler; this.params = params; if (redirectStrategy instanceof DefaultRedirectStrategyAdaptor) { this.redirectHandler = ((DefaultRedirectStrategyAdaptor) redirectStrategy).getHandler(); } else { this.redirectHandler = null; } if (targetAuthStrategy instanceof AuthenticationStrategyAdaptor) { this.targetAuthHandler = ((AuthenticationStrategyAdaptor) targetAuthStrategy).getHandler(); } else { this.targetAuthHandler = null; } if (proxyAuthStrategy instanceof AuthenticationStrategyAdaptor) { this.proxyAuthHandler = ((AuthenticationStrategyAdaptor) proxyAuthStrategy).getHandler(); } else { this.proxyAuthHandler = null; } this.managedConn = null; this.execCount = 0; this.redirectCount = 0; this.targetAuthState = new AuthState(); this.proxyAuthState = new AuthState(); this.maxRedirects = this.params.getIntParameter(ClientPNames.MAX_REDIRECTS, 100); } private RequestWrapper wrapRequest( final HttpRequest request) throws ProtocolException { if (request instanceof HttpEntityEnclosingRequest) { return new EntityEnclosingRequestWrapper( (HttpEntityEnclosingRequest) request); } else { return new RequestWrapper( request); } } protected void rewriteRequestURI( final RequestWrapper request, final HttpRoute route) throws ProtocolException { try { URI uri = request.getURI(); if (route.getProxyHost() != null && !route.isTunnelled()) { // Make sure the request URI is absolute if (!uri.isAbsolute()) { final HttpHost target = route.getTargetHost(); uri = URIUtils.rewriteURI(uri, target, true); } else { uri = URIUtils.rewriteURI(uri); } } else { // Make sure the request URI is relative if (uri.isAbsolute()) { uri = URIUtils.rewriteURI(uri, null, true); } else { uri = URIUtils.rewriteURI(uri); } } request.setURI(uri); } catch (final URISyntaxException ex) { throw new ProtocolException("Invalid URI: " + request.getRequestLine().getUri(), ex); } } // non-javadoc, see interface ClientRequestDirector public HttpResponse execute(final HttpHost targetHost, final HttpRequest request, final HttpContext context) throws HttpException, IOException { context.setAttribute(ClientContext.TARGET_AUTH_STATE, targetAuthState); context.setAttribute(ClientContext.PROXY_AUTH_STATE, proxyAuthState); HttpHost target = targetHost; final HttpRequest orig = request; final RequestWrapper origWrapper = wrapRequest(orig); origWrapper.setParams(params); final HttpRoute origRoute = determineRoute(target, origWrapper, context); virtualHost = (HttpHost) origWrapper.getParams().getParameter(ClientPNames.VIRTUAL_HOST); // HTTPCLIENT-1092 - add the port if necessary if (virtualHost != null && virtualHost.getPort() == -1) { final HttpHost host = (target != null) ? target : origRoute.getTargetHost(); final int port = host.getPort(); if (port != -1){ virtualHost = new HttpHost(virtualHost.getHostName(), port, virtualHost.getSchemeName()); } } RoutedRequest roureq = new RoutedRequest(origWrapper, origRoute); boolean reuse = false; boolean done = false; try { HttpResponse response = null; while (!done) { // In this loop, the RoutedRequest may be replaced by a // followup request and route. The request and route passed // in the method arguments will be replaced. The original // request is still available in 'orig'. final RequestWrapper wrapper = roureq.getRequest(); final HttpRoute route = roureq.getRoute(); response = null; // See if we have a user token bound to the execution context Object userToken = context.getAttribute(ClientContext.USER_TOKEN); // Allocate connection if needed if (managedConn == null) { final ClientConnectionRequest connRequest = connManager.requestConnection( route, userToken); if (orig instanceof AbortableHttpRequest) { ((AbortableHttpRequest) orig).setConnectionRequest(connRequest); } final long timeout = HttpClientParams.getConnectionManagerTimeout(params); try { managedConn = connRequest.getConnection(timeout, TimeUnit.MILLISECONDS); } catch(final InterruptedException interrupted) { Thread.currentThread().interrupt(); throw new InterruptedIOException(); } if (HttpConnectionParams.isStaleCheckingEnabled(params)) { // validate connection if (managedConn.isOpen()) { this.log.debug("Stale connection check"); if (managedConn.isStale()) { this.log.debug("Stale connection detected"); managedConn.close(); } } } } if (orig instanceof AbortableHttpRequest) { ((AbortableHttpRequest) orig).setReleaseTrigger(managedConn); } try { tryConnect(roureq, context); } catch (final TunnelRefusedException ex) { if (this.log.isDebugEnabled()) { this.log.debug(ex.getMessage()); } response = ex.getResponse(); break; } final String userinfo = wrapper.getURI().getUserInfo(); if (userinfo != null) { targetAuthState.update( new BasicScheme(), new UsernamePasswordCredentials(userinfo)); } // Get target. Even if there's virtual host, we may need the target to set the port. if (virtualHost != null) { target = virtualHost; } else { final URI requestURI = wrapper.getURI(); if (requestURI.isAbsolute()) { target = URIUtils.extractHost(requestURI); } } if (target == null) { target = route.getTargetHost(); } // Reset headers on the request wrapper wrapper.resetHeaders(); // Re-write request URI if needed rewriteRequestURI(wrapper, route); // Populate the execution context context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target); context.setAttribute(ClientContext.ROUTE, route); context.setAttribute(ExecutionContext.HTTP_CONNECTION, managedConn); // Run request protocol interceptors requestExec.preProcess(wrapper, httpProcessor, context); response = tryExecute(roureq, context); if (response == null) { // Need to start over continue; } // Run response protocol interceptors response.setParams(params); requestExec.postProcess(response, httpProcessor, context); // The connection is in or can be brought to a re-usable state. reuse = reuseStrategy.keepAlive(response, context); if (reuse) { // Set the idle duration of this connection final long duration = keepAliveStrategy.getKeepAliveDuration(response, context); if (this.log.isDebugEnabled()) { final String s; if (duration > 0) { s = "for " + duration + " " + TimeUnit.MILLISECONDS; } else { s = "indefinitely"; } this.log.debug("Connection can be kept alive " + s); } managedConn.setIdleDuration(duration, TimeUnit.MILLISECONDS); } final RoutedRequest followup = handleResponse(roureq, response, context); if (followup == null) { done = true; } else { if (reuse) { // Make sure the response body is fully consumed, if present final HttpEntity entity = response.getEntity(); EntityUtils.consume(entity); // entity consumed above is not an auto-release entity, // need to mark the connection re-usable explicitly managedConn.markReusable(); } else { managedConn.close(); if (proxyAuthState.getState().compareTo(AuthProtocolState.CHALLENGED) > 0 && proxyAuthState.getAuthScheme() != null && proxyAuthState.getAuthScheme().isConnectionBased()) { this.log.debug("Resetting proxy auth state"); proxyAuthState.reset(); } if (targetAuthState.getState().compareTo(AuthProtocolState.CHALLENGED) > 0 && targetAuthState.getAuthScheme() != null && targetAuthState.getAuthScheme().isConnectionBased()) { this.log.debug("Resetting target auth state"); targetAuthState.reset(); } } // check if we can use the same connection for the followup if (!followup.getRoute().equals(roureq.getRoute())) { releaseConnection(); } roureq = followup; } if (managedConn != null) { if (userToken == null) { userToken = userTokenHandler.getUserToken(context); context.setAttribute(ClientContext.USER_TOKEN, userToken); } if (userToken != null) { managedConn.setState(userToken); } } } // while not done // check for entity, release connection if possible if ((response == null) || (response.getEntity() == null) || !response.getEntity().isStreaming()) { // connection not needed and (assumed to be) in re-usable state if (reuse) { managedConn.markReusable(); } releaseConnection(); } else { // install an auto-release entity HttpEntity entity = response.getEntity(); entity = new BasicManagedEntity(entity, managedConn, reuse); response.setEntity(entity); } return response; } catch (final ConnectionShutdownException ex) { final InterruptedIOException ioex = new InterruptedIOException( "Connection has been shut down"); ioex.initCause(ex); throw ioex; } catch (final HttpException ex) { abortConnection(); throw ex; } catch (final IOException ex) { abortConnection(); throw ex; } catch (final RuntimeException ex) { abortConnection(); throw ex; } } // execute /** * Establish connection either directly or through a tunnel and retry in case of * a recoverable I/O failure */ private void tryConnect( final RoutedRequest req, final HttpContext context) throws HttpException, IOException { final HttpRoute route = req.getRoute(); final HttpRequest wrapper = req.getRequest(); int connectCount = 0; for (;;) { context.setAttribute(ExecutionContext.HTTP_REQUEST, wrapper); // Increment connect count connectCount++; try { if (!managedConn.isOpen()) { managedConn.open(route, context, params); } else { managedConn.setSocketTimeout(HttpConnectionParams.getSoTimeout(params)); } establishRoute(route, context); break; } catch (final IOException ex) { try { managedConn.close(); } catch (final IOException ignore) { } if (retryHandler.retryRequest(ex, connectCount, context)) { if (this.log.isInfoEnabled()) { this.log.info("I/O exception ("+ ex.getClass().getName() + ") caught when connecting to " + route + ": " + ex.getMessage()); if (this.log.isDebugEnabled()) { this.log.debug(ex.getMessage(), ex); } this.log.info("Retrying connect to " + route); } } else { throw ex; } } } } /** * Execute request and retry in case of a recoverable I/O failure */ private HttpResponse tryExecute( final RoutedRequest req, final HttpContext context) throws HttpException, IOException { final RequestWrapper wrapper = req.getRequest(); final HttpRoute route = req.getRoute(); HttpResponse response = null; Exception retryReason = null; for (;;) { // Increment total exec count (with redirects) execCount++; // Increment exec count for this particular request wrapper.incrementExecCount(); if (!wrapper.isRepeatable()) { this.log.debug("Cannot retry non-repeatable request"); if (retryReason != null) { throw new NonRepeatableRequestException("Cannot retry request " + "with a non-repeatable request entity. The cause lists the " + "reason the original request failed.", retryReason); } else { throw new NonRepeatableRequestException("Cannot retry request " + "with a non-repeatable request entity."); } } try { if (!managedConn.isOpen()) { // If we have a direct route to the target host // just re-open connection and re-try the request if (!route.isTunnelled()) { this.log.debug("Reopening the direct connection."); managedConn.open(route, context, params); } else { // otherwise give up this.log.debug("Proxied connection. Need to start over."); break; } } if (this.log.isDebugEnabled()) { this.log.debug("Attempt " + execCount + " to execute request"); } response = requestExec.execute(wrapper, managedConn, context); break; } catch (final IOException ex) { this.log.debug("Closing the connection."); try { managedConn.close(); } catch (final IOException ignore) { } if (retryHandler.retryRequest(ex, wrapper.getExecCount(), context)) { if (this.log.isInfoEnabled()) { this.log.info("I/O exception ("+ ex.getClass().getName() + ") caught when processing request to " + route + ": " + ex.getMessage()); } if (this.log.isDebugEnabled()) { this.log.debug(ex.getMessage(), ex); } if (this.log.isInfoEnabled()) { this.log.info("Retrying request to " + route); } retryReason = ex; } else { if (ex instanceof NoHttpResponseException) { final NoHttpResponseException updatedex = new NoHttpResponseException( route.getTargetHost().toHostString() + " failed to respond"); updatedex.setStackTrace(ex.getStackTrace()); throw updatedex; } else { throw ex; } } } } return response; } /** * Returns the connection back to the connection manager * and prepares for retrieving a new connection during * the next request. */ protected void releaseConnection() { // Release the connection through the ManagedConnection instead of the // ConnectionManager directly. This lets the connection control how // it is released. try { managedConn.releaseConnection(); } catch(final IOException ignored) { this.log.debug("IOException releasing connection", ignored); } managedConn = null; } /** * Determines the route for a request. * Called by {@link #execute} * to determine the route for either the original or a followup request. * * @param targetHost the target host for the request. * Implementations may accept null * if they can still determine a route, for example * to a default target or by inspecting the request. * @param request the request to execute * @param context the context to use for the execution, * never null * * @return the route the request should take * * @throws HttpException in case of a problem */ protected HttpRoute determineRoute(final HttpHost targetHost, final HttpRequest request, final HttpContext context) throws HttpException { return this.routePlanner.determineRoute( targetHost != null ? targetHost : (HttpHost) request.getParams() .getParameter(ClientPNames.DEFAULT_HOST), request, context); } /** * Establishes the target route. * * @param route the route to establish * @param context the context for the request execution * * @throws HttpException in case of a problem * @throws IOException in case of an IO problem */ protected void establishRoute(final HttpRoute route, final HttpContext context) throws HttpException, IOException { final HttpRouteDirector rowdy = new BasicRouteDirector(); int step; do { final HttpRoute fact = managedConn.getRoute(); step = rowdy.nextStep(route, fact); switch (step) { case HttpRouteDirector.CONNECT_TARGET: case HttpRouteDirector.CONNECT_PROXY: managedConn.open(route, context, this.params); break; case HttpRouteDirector.TUNNEL_TARGET: { final boolean secure = createTunnelToTarget(route, context); this.log.debug("Tunnel to target created."); managedConn.tunnelTarget(secure, this.params); } break; case HttpRouteDirector.TUNNEL_PROXY: { // The most simple example for this case is a proxy chain // of two proxies, where P1 must be tunnelled to P2. // route: Source -> P1 -> P2 -> Target (3 hops) // fact: Source -> P1 -> Target (2 hops) final int hop = fact.getHopCount()-1; // the hop to establish final boolean secure = createTunnelToProxy(route, hop, context); this.log.debug("Tunnel to proxy created."); managedConn.tunnelProxy(route.getHopTarget(hop), secure, this.params); } break; case HttpRouteDirector.LAYER_PROTOCOL: managedConn.layerProtocol(context, this.params); break; case HttpRouteDirector.UNREACHABLE: throw new HttpException("Unable to establish route: " + "planned = " + route + "; current = " + fact); case HttpRouteDirector.COMPLETE: // do nothing break; default: throw new IllegalStateException("Unknown step indicator " + step + " from RouteDirector."); } } while (step > HttpRouteDirector.COMPLETE); } // establishConnection /** * Creates a tunnel to the target server. * The connection must be established to the (last) proxy. * A CONNECT request for tunnelling through the proxy will * be created and sent, the response received and checked. * This method does not update the connection with * information about the tunnel, that is left to the caller. * * @param route the route to establish * @param context the context for request execution * * @return true if the tunnelled route is secure, * false otherwise. * The implementation here always returns false, * but derived classes may override. * * @throws HttpException in case of a problem * @throws IOException in case of an IO problem */ protected boolean createTunnelToTarget(final HttpRoute route, final HttpContext context) throws HttpException, IOException { final HttpHost proxy = route.getProxyHost(); final HttpHost target = route.getTargetHost(); HttpResponse response = null; for (;;) { if (!this.managedConn.isOpen()) { this.managedConn.open(route, context, this.params); } final HttpRequest connect = createConnectRequest(route, context); connect.setParams(this.params); // Populate the execution context context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target); context.setAttribute(ExecutionContext.HTTP_PROXY_HOST, proxy); context.setAttribute(ExecutionContext.HTTP_CONNECTION, managedConn); context.setAttribute(ExecutionContext.HTTP_REQUEST, connect); this.requestExec.preProcess(connect, this.httpProcessor, context); response = this.requestExec.execute(connect, this.managedConn, context); response.setParams(this.params); this.requestExec.postProcess(response, this.httpProcessor, context); final int status = response.getStatusLine().getStatusCode(); if (status < 200) { throw new HttpException("Unexpected response to CONNECT request: " + response.getStatusLine()); } if (HttpClientParams.isAuthenticating(this.params)) { if (this.authenticator.isAuthenticationRequested(proxy, response, this.proxyAuthStrategy, this.proxyAuthState, context)) { if (this.authenticator.authenticate(proxy, response, this.proxyAuthStrategy, this.proxyAuthState, context)) { // Retry request if (this.reuseStrategy.keepAlive(response, context)) { this.log.debug("Connection kept alive"); // Consume response content final HttpEntity entity = response.getEntity(); EntityUtils.consume(entity); } else { this.managedConn.close(); } } else { break; } } else { break; } } } final int status = response.getStatusLine().getStatusCode(); if (status > 299) { // Buffer response content final HttpEntity entity = response.getEntity(); if (entity != null) { response.setEntity(new BufferedHttpEntity(entity)); } this.managedConn.close(); throw new TunnelRefusedException("CONNECT refused by proxy: " + response.getStatusLine(), response); } this.managedConn.markReusable(); // How to decide on security of the tunnelled connection? // The socket factory knows only about the segment to the proxy. // Even if that is secure, the hop to the target may be insecure. // Leave it to derived classes, consider insecure by default here. return false; } // createTunnelToTarget /** * Creates a tunnel to an intermediate proxy. * This method is not implemented in this class. * It just throws an exception here. * * @param route the route to establish * @param hop the hop in the route to establish now. * route.getHopTarget(hop) * will return the proxy to tunnel to. * @param context the context for request execution * * @return true if the partially tunnelled connection * is secure, false otherwise. * * @throws HttpException in case of a problem * @throws IOException in case of an IO problem */ protected boolean createTunnelToProxy(final HttpRoute route, final int hop, final HttpContext context) throws HttpException, IOException { // Have a look at createTunnelToTarget and replicate the parts // you need in a custom derived class. If your proxies don't require // authentication, it is not too hard. But for the stock version of // HttpClient, we cannot make such simplifying assumptions and would // have to include proxy authentication code. The HttpComponents team // is currently not in a position to support rarely used code of this // complexity. Feel free to submit patches that refactor the code in // createTunnelToTarget to facilitate re-use for proxy tunnelling. throw new HttpException("Proxy chains are not supported."); } /** * Creates the CONNECT request for tunnelling. * Called by {@link #createTunnelToTarget createTunnelToTarget}. * * @param route the route to establish * @param context the context for request execution * * @return the CONNECT request for tunnelling */ protected HttpRequest createConnectRequest(final HttpRoute route, final HttpContext context) { // see RFC 2817, section 5.2 and // INTERNET-DRAFT: Tunneling TCP based protocols through // Web proxy servers final HttpHost target = route.getTargetHost(); final String host = target.getHostName(); int port = target.getPort(); if (port < 0) { final Scheme scheme = connManager.getSchemeRegistry(). getScheme(target.getSchemeName()); port = scheme.getDefaultPort(); } final StringBuilder buffer = new StringBuilder(host.length() + 6); buffer.append(host); buffer.append(':'); buffer.append(Integer.toString(port)); final String authority = buffer.toString(); final ProtocolVersion ver = HttpProtocolParams.getVersion(params); final HttpRequest req = new BasicHttpRequest ("CONNECT", authority, ver); return req; } /** * Analyzes a response to check need for a followup. * * @param roureq the request and route. * @param response the response to analayze * @param context the context used for the current request execution * * @return the followup request and route if there is a followup, or * null if the response should be returned as is * * @throws HttpException in case of a problem * @throws IOException in case of an IO problem */ protected RoutedRequest handleResponse(final RoutedRequest roureq, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final HttpRoute route = roureq.getRoute(); final RequestWrapper request = roureq.getRequest(); final HttpParams params = request.getParams(); if (HttpClientParams.isAuthenticating(params)) { HttpHost target = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST); if (target == null) { target = route.getTargetHost(); } if (target.getPort() < 0) { final Scheme scheme = connManager.getSchemeRegistry().getScheme(target); target = new HttpHost(target.getHostName(), scheme.getDefaultPort(), target.getSchemeName()); } final boolean targetAuthRequested = this.authenticator.isAuthenticationRequested( target, response, this.targetAuthStrategy, targetAuthState, context); HttpHost proxy = route.getProxyHost(); // if proxy is not set use target host instead if (proxy == null) { proxy = route.getTargetHost(); } final boolean proxyAuthRequested = this.authenticator.isAuthenticationRequested( proxy, response, this.proxyAuthStrategy, proxyAuthState, context); if (targetAuthRequested) { if (this.authenticator.authenticate(target, response, this.targetAuthStrategy, this.targetAuthState, context)) { // Re-try the same request via the same route return roureq; } } if (proxyAuthRequested) { if (this.authenticator.authenticate(proxy, response, this.proxyAuthStrategy, this.proxyAuthState, context)) { // Re-try the same request via the same route return roureq; } } } if (HttpClientParams.isRedirecting(params) && this.redirectStrategy.isRedirected(request, response, context)) { if (redirectCount >= maxRedirects) { throw new RedirectException("Maximum redirects (" + maxRedirects + ") exceeded"); } redirectCount++; // Virtual host cannot be used any longer virtualHost = null; final HttpUriRequest redirect = redirectStrategy.getRedirect(request, response, context); final HttpRequest orig = request.getOriginal(); redirect.setHeaders(orig.getAllHeaders()); final URI uri = redirect.getURI(); final HttpHost newTarget = URIUtils.extractHost(uri); if (newTarget == null) { throw new ProtocolException("Redirect URI does not specify a valid host name: " + uri); } // Reset auth states if redirecting to another host if (!route.getTargetHost().equals(newTarget)) { this.log.debug("Resetting target auth state"); targetAuthState.reset(); final AuthScheme authScheme = proxyAuthState.getAuthScheme(); if (authScheme != null && authScheme.isConnectionBased()) { this.log.debug("Resetting proxy auth state"); proxyAuthState.reset(); } } final RequestWrapper wrapper = wrapRequest(redirect); wrapper.setParams(params); final HttpRoute newRoute = determineRoute(newTarget, wrapper, context); final RoutedRequest newRequest = new RoutedRequest(wrapper, newRoute); if (this.log.isDebugEnabled()) { this.log.debug("Redirecting to '" + uri + "' via " + newRoute); } return newRequest; } return null; } // handleResponse /** * Shuts down the connection. * This method is called from a catch block in * {@link #execute execute} during exception handling. */ private void abortConnection() { final ManagedClientConnection mcc = managedConn; if (mcc != null) { // we got here as the result of an exception // no response will be returned, release the connection managedConn = null; try { mcc.abortConnection(); } catch (final IOException ex) { if (this.log.isDebugEnabled()) { this.log.debug(ex.getMessage(), ex); } } // ensure the connection manager properly releases this connection try { mcc.releaseConnection(); } catch(final IOException ignored) { this.log.debug("Error releasing connection", ignored); } } } // abortConnection } // class DefaultClientRequestDirector ././@LongLink0100644 0000000 0000000 00000000204 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/DefaultTargetAuthenticationHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/DefaultT0100644 0000000 0000000 00000006113 12301751666 032372 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.List; import java.util.Map; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AUTH; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.auth.params.AuthPNames; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Default {@link org.apache.http.client.AuthenticationHandler} implementation * for target host authentication. * * @since 4.0 * * @deprecated (4.2) use {@link TargetAuthenticationStrategy} */ @Deprecated @Immutable public class DefaultTargetAuthenticationHandler extends AbstractAuthenticationHandler { public DefaultTargetAuthenticationHandler() { super(); } public boolean isAuthenticationRequested( final HttpResponse response, final HttpContext context) { Args.notNull(response, "HTTP response"); final int status = response.getStatusLine().getStatusCode(); return status == HttpStatus.SC_UNAUTHORIZED; } public Map getChallenges( final HttpResponse response, final HttpContext context) throws MalformedChallengeException { Args.notNull(response, "HTTP response"); final Header[] headers = response.getHeaders(AUTH.WWW_AUTH); return parseChallenges(headers); } @Override protected List getAuthPreferences( final HttpResponse response, final HttpContext context) { @SuppressWarnings("unchecked") final List authpref = (List) response.getParams().getParameter( AuthPNames.TARGET_AUTH_PREF); if (authpref != null) { return authpref; } else { return super.getAuthPreferences(response, context); } } } ././@LongLink0100644 0000000 0000000 00000000163 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/HttpAuthenticator.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/HttpAuth0100644 0000000 0000000 00000004060 12301751666 032422 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.commons.logging.Log; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.auth.AuthState; import org.apache.http.client.AuthenticationStrategy; import org.apache.http.protocol.HttpContext; /** * @deprecated (4.3) reserved for internal use. * */ @Deprecated public class HttpAuthenticator extends org.apache.http.impl.auth.HttpAuthenticator { public HttpAuthenticator(final Log log) { super(log); } public HttpAuthenticator() { super(); } public boolean authenticate ( final HttpHost host, final HttpResponse response, final AuthenticationStrategy authStrategy, final AuthState authState, final HttpContext context) { return handleAuthChallenge(host, response, authStrategy, authState, context); } } ././@LongLink0100644 0000000 0000000 00000000157 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/RoutedRequest.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/RoutedRe0100644 0000000 0000000 00000004036 12301751666 032415 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.conn.routing.HttpRoute; /** * A request with the route along which it should be sent. * * @since 4.0 * * @deprecated (4.3) do not use. */ @Deprecated @NotThreadSafe // RequestWrapper is @NotThreadSafe public class RoutedRequest { protected final RequestWrapper request; // @NotThreadSafe protected final HttpRoute route; // @Immutable /** * Creates a new routed request. * * @param req the request * @param route the route */ public RoutedRequest(final RequestWrapper req, final HttpRoute route) { super(); this.request = req; this.route = route; } public final RequestWrapper getRequest() { return request; } public final HttpRoute getRoute() { return route; } } ././@LongLink0100644 0000000 0000000 00000000171 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/SystemDefaultHttpClient.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/SystemDe0100644 0000000 0000000 00000014733 12301751666 032426 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.net.ProxySelector; import org.apache.http.ConnectionReuseStrategy; import org.apache.http.annotation.ThreadSafe; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.impl.DefaultConnectionReuseStrategy; import org.apache.http.impl.NoConnectionReuseStrategy; import org.apache.http.impl.conn.PoolingClientConnectionManager; import org.apache.http.impl.conn.ProxySelectorRoutePlanner; import org.apache.http.impl.conn.SchemeRegistryFactory; import org.apache.http.params.HttpParams; /** * An extension of {@link DefaultHttpClient} pre-configured using system properties. *

* The following system properties are taken into account by this class: *

    *
  • ssl.TrustManagerFactory.algorithm
  • *
  • javax.net.ssl.trustStoreType
  • *
  • javax.net.ssl.trustStore
  • *
  • javax.net.ssl.trustStoreProvider
  • *
  • javax.net.ssl.trustStorePassword
  • *
  • java.home
  • *
  • ssl.KeyManagerFactory.algorithm
  • *
  • javax.net.ssl.keyStoreType
  • *
  • javax.net.ssl.keyStore
  • *
  • javax.net.ssl.keyStoreProvider
  • *
  • javax.net.ssl.keyStorePassword
  • *
  • http.proxyHost
  • *
  • http.proxyPort
  • *
  • http.nonProxyHosts
  • *
  • http.keepAlive
  • *
  • http.maxConnections
  • *
*

*

* The following parameters can be used to customize the behavior of this * class: *

    *
  • {@link org.apache.http.params.CoreProtocolPNames#PROTOCOL_VERSION}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#USE_EXPECT_CONTINUE}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#WAIT_FOR_CONTINUE}
  • *
  • {@link org.apache.http.params.CoreProtocolPNames#USER_AGENT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_REUSEADDR}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#STALE_CONNECTION_CHECK}
  • *
  • {@link org.apache.http.conn.params.ConnRoutePNames#FORCED_ROUTE}
  • *
  • {@link org.apache.http.conn.params.ConnRoutePNames#LOCAL_ADDRESS}
  • *
  • {@link org.apache.http.conn.params.ConnRoutePNames#DEFAULT_PROXY}
  • *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#DATE_PATTERNS}
  • *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#SINGLE_COOKIE_HEADER}
  • *
  • {@link org.apache.http.auth.params.AuthPNames#CREDENTIAL_CHARSET}
  • *
  • {@link org.apache.http.client.params.ClientPNames#COOKIE_POLICY}
  • *
  • {@link org.apache.http.client.params.ClientPNames#HANDLE_AUTHENTICATION}
  • *
  • {@link org.apache.http.client.params.ClientPNames#HANDLE_REDIRECTS}
  • *
  • {@link org.apache.http.client.params.ClientPNames#MAX_REDIRECTS}
  • *
  • {@link org.apache.http.client.params.ClientPNames#ALLOW_CIRCULAR_REDIRECTS}
  • *
  • {@link org.apache.http.client.params.ClientPNames#VIRTUAL_HOST}
  • *
  • {@link org.apache.http.client.params.ClientPNames#DEFAULT_HOST}
  • *
  • {@link org.apache.http.client.params.ClientPNames#DEFAULT_HEADERS}
  • *
  • {@link org.apache.http.client.params.ClientPNames#CONN_MANAGER_TIMEOUT}
  • *
*

* * @since 4.2 * * @deprecated (4.3) use {@link HttpClientBuilder} */ @ThreadSafe @Deprecated public class SystemDefaultHttpClient extends DefaultHttpClient { public SystemDefaultHttpClient(final HttpParams params) { super(null, params); } public SystemDefaultHttpClient() { super(null, null); } @Override protected ClientConnectionManager createClientConnectionManager() { final PoolingClientConnectionManager connmgr = new PoolingClientConnectionManager( SchemeRegistryFactory.createSystemDefault()); String s = System.getProperty("http.keepAlive", "true"); if ("true".equalsIgnoreCase(s)) { s = System.getProperty("http.maxConnections", "5"); final int max = Integer.parseInt(s); connmgr.setDefaultMaxPerRoute(max); connmgr.setMaxTotal(2 * max); } return connmgr; } @Override protected HttpRoutePlanner createHttpRoutePlanner() { return new ProxySelectorRoutePlanner(getConnectionManager().getSchemeRegistry(), ProxySelector.getDefault()); } @Override protected ConnectionReuseStrategy createConnectionReuseStrategy() { final String s = System.getProperty("http.keepAlive", "true"); if ("true".equalsIgnoreCase(s)) { return new DefaultConnectionReuseStrategy(); } else { return new NoConnectionReuseStrategy(); } } } ././@LongLink0100644 0000000 0000000 00000000170 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/TunnelRefusedException.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/client/TunnelRe0100644 0000000 0000000 00000003575 12301751666 032427 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.HttpException; import org.apache.http.HttpResponse; import org.apache.http.annotation.Immutable; /** * Signals that the tunnel request was rejected by the proxy host. * * @since 4.0 * * @deprecated (4.3) reserved for internal use. */ @Deprecated @Immutable public class TunnelRefusedException extends HttpException { private static final long serialVersionUID = -8646722842745617323L; private final HttpResponse response; public TunnelRefusedException(final String message, final HttpResponse response) { super(message); this.response = response; } public HttpResponse getResponse() { return this.response; } } httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/0040755 0000000 0000000 00000000000 12301751665 030417 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000171 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/AbstractClientConnAdapter.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/AbstractCl0100644 0000000 0000000 00000026622 12301751665 032371 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.io.InterruptedIOException; import java.net.InetAddress; import java.net.Socket; import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import org.apache.http.HttpConnectionMetrics; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.ManagedClientConnection; import org.apache.http.conn.OperatedClientConnection; import org.apache.http.protocol.HttpContext; /** * Abstract adapter from {@link OperatedClientConnection operated} to * {@link ManagedClientConnection managed} client connections. * Read and write methods are delegated to the wrapped connection. * Operations affecting the connection state have to be implemented * by derived classes. Operations for querying the connection state * are delegated to the wrapped connection if there is one, or * return a default value if there is none. *

* This adapter tracks the checkpoints for reusable communication states, * as indicated by {@link #markReusable markReusable} and queried by * {@link #isMarkedReusable isMarkedReusable}. * All send and receive operations will automatically clear the mark. *

* Connection release calls are delegated to the connection manager, * if there is one. {@link #abortConnection abortConnection} will * clear the reusability mark first. The connection manager is * expected to tolerate multiple calls to the release method. * * @since 4.0 * * @deprecated (4.2) do not use */ @Deprecated @NotThreadSafe public abstract class AbstractClientConnAdapter implements ManagedClientConnection, HttpContext { /** * The connection manager. */ private final ClientConnectionManager connManager; /** The wrapped connection. */ private volatile OperatedClientConnection wrappedConnection; /** The reusability marker. */ private volatile boolean markedReusable; /** True if the connection has been shut down or released. */ private volatile boolean released; /** The duration this is valid for while idle (in ms). */ private volatile long duration; /** * Creates a new connection adapter. * The adapter is initially not * {@link #isMarkedReusable marked} as reusable. * * @param mgr the connection manager, or null * @param conn the connection to wrap, or null */ protected AbstractClientConnAdapter(final ClientConnectionManager mgr, final OperatedClientConnection conn) { super(); connManager = mgr; wrappedConnection = conn; markedReusable = false; released = false; duration = Long.MAX_VALUE; } /** * Detaches this adapter from the wrapped connection. * This adapter becomes useless. */ protected synchronized void detach() { wrappedConnection = null; duration = Long.MAX_VALUE; } protected OperatedClientConnection getWrappedConnection() { return wrappedConnection; } protected ClientConnectionManager getManager() { return connManager; } /** * @deprecated (4.1) use {@link #assertValid(OperatedClientConnection)} */ @Deprecated protected final void assertNotAborted() throws InterruptedIOException { if (isReleased()) { throw new InterruptedIOException("Connection has been shut down"); } } /** * @since 4.1 * @return value of released flag */ protected boolean isReleased() { return released; } /** * Asserts that there is a valid wrapped connection to delegate to. * * @throws ConnectionShutdownException if there is no wrapped connection * or connection has been aborted */ protected final void assertValid( final OperatedClientConnection wrappedConn) throws ConnectionShutdownException { if (isReleased() || wrappedConn == null) { throw new ConnectionShutdownException(); } } public boolean isOpen() { final OperatedClientConnection conn = getWrappedConnection(); if (conn == null) { return false; } return conn.isOpen(); } public boolean isStale() { if (isReleased()) { return true; } final OperatedClientConnection conn = getWrappedConnection(); if (conn == null) { return true; } return conn.isStale(); } public void setSocketTimeout(final int timeout) { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); conn.setSocketTimeout(timeout); } public int getSocketTimeout() { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); return conn.getSocketTimeout(); } public HttpConnectionMetrics getMetrics() { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); return conn.getMetrics(); } public void flush() throws IOException { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); conn.flush(); } public boolean isResponseAvailable(final int timeout) throws IOException { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); return conn.isResponseAvailable(timeout); } public void receiveResponseEntity(final HttpResponse response) throws HttpException, IOException { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); unmarkReusable(); conn.receiveResponseEntity(response); } public HttpResponse receiveResponseHeader() throws HttpException, IOException { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); unmarkReusable(); return conn.receiveResponseHeader(); } public void sendRequestEntity(final HttpEntityEnclosingRequest request) throws HttpException, IOException { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); unmarkReusable(); conn.sendRequestEntity(request); } public void sendRequestHeader(final HttpRequest request) throws HttpException, IOException { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); unmarkReusable(); conn.sendRequestHeader(request); } public InetAddress getLocalAddress() { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); return conn.getLocalAddress(); } public int getLocalPort() { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); return conn.getLocalPort(); } public InetAddress getRemoteAddress() { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); return conn.getRemoteAddress(); } public int getRemotePort() { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); return conn.getRemotePort(); } public boolean isSecure() { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); return conn.isSecure(); } public void bind(final Socket socket) throws IOException { throw new UnsupportedOperationException(); } public Socket getSocket() { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); if (!isOpen()) { return null; } return conn.getSocket(); } public SSLSession getSSLSession() { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); if (!isOpen()) { return null; } SSLSession result = null; final Socket sock = conn.getSocket(); if (sock instanceof SSLSocket) { result = ((SSLSocket)sock).getSession(); } return result; } public void markReusable() { markedReusable = true; } public void unmarkReusable() { markedReusable = false; } public boolean isMarkedReusable() { return markedReusable; } public void setIdleDuration(final long duration, final TimeUnit unit) { if(duration > 0) { this.duration = unit.toMillis(duration); } else { this.duration = -1; } } public synchronized void releaseConnection() { if (released) { return; } released = true; connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS); } public synchronized void abortConnection() { if (released) { return; } released = true; unmarkReusable(); try { shutdown(); } catch (final IOException ignore) { } connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS); } public Object getAttribute(final String id) { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); if (conn instanceof HttpContext) { return ((HttpContext) conn).getAttribute(id); } else { return null; } } public Object removeAttribute(final String id) { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); if (conn instanceof HttpContext) { return ((HttpContext) conn).removeAttribute(id); } else { return null; } } public void setAttribute(final String id, final Object obj) { final OperatedClientConnection conn = getWrappedConnection(); assertValid(conn); if (conn instanceof HttpContext) { ((HttpContext) conn).setAttribute(id, obj); } } } ././@LongLink0100644 0000000 0000000 00000000171 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/AbstractPooledConnAdapter.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/AbstractPo0100644 0000000 0000000 00000013713 12301751664 032405 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import org.apache.http.HttpHost; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.OperatedClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; /** * Abstract adapter from pool {@link AbstractPoolEntry entries} to * {@link org.apache.http.conn.ManagedClientConnection managed} * client connections. * The connection in the pool entry is used to initialize the base class. * In addition, methods to establish a route are delegated to the * pool entry. {@link #shutdown shutdown} and {@link #close close} * will clear the tracked route in the pool entry and call the * respective method of the wrapped connection. * * @since 4.0 * * @deprecated (4.2) do not use */ @Deprecated public abstract class AbstractPooledConnAdapter extends AbstractClientConnAdapter { /** The wrapped pool entry. */ protected volatile AbstractPoolEntry poolEntry; /** * Creates a new connection adapter. * * @param manager the connection manager * @param entry the pool entry for the connection being wrapped */ protected AbstractPooledConnAdapter(final ClientConnectionManager manager, final AbstractPoolEntry entry) { super(manager, entry.connection); this.poolEntry = entry; } public String getId() { return null; } /** * Obtains the pool entry. * * @return the pool entry, or null if detached * * @deprecated (4.0.1) */ @Deprecated protected AbstractPoolEntry getPoolEntry() { return this.poolEntry; } /** * Asserts that there is a valid pool entry. * * @throws ConnectionShutdownException if there is no pool entry * or connection has been aborted * * @see #assertValid(OperatedClientConnection) */ protected void assertValid(final AbstractPoolEntry entry) { if (isReleased() || entry == null) { throw new ConnectionShutdownException(); } } /** * @deprecated (4.1) use {@link #assertValid(AbstractPoolEntry)} */ @Deprecated protected final void assertAttached() { if (poolEntry == null) { throw new ConnectionShutdownException(); } } /** * Detaches this adapter from the wrapped connection. * This adapter becomes useless. */ @Override protected synchronized void detach() { poolEntry = null; super.detach(); } public HttpRoute getRoute() { final AbstractPoolEntry entry = getPoolEntry(); assertValid(entry); return (entry.tracker == null) ? null : entry.tracker.toRoute(); } public void open(final HttpRoute route, final HttpContext context, final HttpParams params) throws IOException { final AbstractPoolEntry entry = getPoolEntry(); assertValid(entry); entry.open(route, context, params); } public void tunnelTarget(final boolean secure, final HttpParams params) throws IOException { final AbstractPoolEntry entry = getPoolEntry(); assertValid(entry); entry.tunnelTarget(secure, params); } public void tunnelProxy(final HttpHost next, final boolean secure, final HttpParams params) throws IOException { final AbstractPoolEntry entry = getPoolEntry(); assertValid(entry); entry.tunnelProxy(next, secure, params); } public void layerProtocol(final HttpContext context, final HttpParams params) throws IOException { final AbstractPoolEntry entry = getPoolEntry(); assertValid(entry); entry.layerProtocol(context, params); } public void close() throws IOException { final AbstractPoolEntry entry = getPoolEntry(); if (entry != null) { entry.shutdownEntry(); } final OperatedClientConnection conn = getWrappedConnection(); if (conn != null) { conn.close(); } } public void shutdown() throws IOException { final AbstractPoolEntry entry = getPoolEntry(); if (entry != null) { entry.shutdownEntry(); } final OperatedClientConnection conn = getWrappedConnection(); if (conn != null) { conn.shutdown(); } } public Object getState() { final AbstractPoolEntry entry = getPoolEntry(); assertValid(entry); return entry.getState(); } public void setState(final Object state) { final AbstractPoolEntry entry = getPoolEntry(); assertValid(entry); entry.setState(state); } } ././@LongLink0100644 0000000 0000000 00000000161 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/AbstractPoolEntry.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/AbstractPo0100644 0000000 0000000 00000022413 12301751665 032403 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.io.InterruptedIOException; import org.apache.http.HttpHost; import org.apache.http.conn.ClientConnectionOperator; import org.apache.http.conn.OperatedClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.RouteTracker; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.Asserts; /** * A pool entry for use by connection manager implementations. * Pool entries work in conjunction with an * {@link AbstractClientConnAdapter adapter}. * The adapter is handed out to applications that obtain a connection. * The pool entry stores the underlying connection and tracks the * {@link HttpRoute route} established. * The adapter delegates methods for establishing the route to * its pool entry. *

* If the managed connections is released or revoked, the adapter * gets disconnected, but the pool entry still contains the * underlying connection and the established route. * * @since 4.0 * * @deprecated (4.2) do not use */ @Deprecated public abstract class AbstractPoolEntry { /** The connection operator. */ protected final ClientConnectionOperator connOperator; /** The underlying connection being pooled or used. */ protected final OperatedClientConnection connection; /** The route for which this entry gets allocated. */ //@@@ currently accessed from connection manager(s) as attribute //@@@ avoid that, derived classes should decide whether update is allowed //@@@ SCCM: yes, TSCCM: no protected volatile HttpRoute route; /** Connection state object */ protected volatile Object state; /** The tracked route, or null before tracking starts. */ protected volatile RouteTracker tracker; /** * Creates a new pool entry. * * @param connOperator the Connection Operator for this entry * @param route the planned route for the connection, * or null */ protected AbstractPoolEntry(final ClientConnectionOperator connOperator, final HttpRoute route) { super(); Args.notNull(connOperator, "Connection operator"); this.connOperator = connOperator; this.connection = connOperator.createConnection(); this.route = route; this.tracker = null; } /** * Returns the state object associated with this pool entry. * * @return The state object */ public Object getState() { return state; } /** * Assigns a state object to this pool entry. * * @param state The state object */ public void setState(final Object state) { this.state = state; } /** * Opens the underlying connection. * * @param route the route along which to open the connection * @param context the context for opening the connection * @param params the parameters for opening the connection * * @throws IOException in case of a problem */ public void open(final HttpRoute route, final HttpContext context, final HttpParams params) throws IOException { Args.notNull(route, "Route"); Args.notNull(params, "HTTP parameters"); if (this.tracker != null) { Asserts.check(!this.tracker.isConnected(), "Connection already open"); } // - collect the arguments // - call the operator // - update the tracking data // In this order, we can be sure that only a successful // opening of the connection will be tracked. this.tracker = new RouteTracker(route); final HttpHost proxy = route.getProxyHost(); connOperator.openConnection (this.connection, (proxy != null) ? proxy : route.getTargetHost(), route.getLocalAddress(), context, params); final RouteTracker localTracker = tracker; // capture volatile // If this tracker was reset while connecting, // fail early. if (localTracker == null) { throw new InterruptedIOException("Request aborted"); } if (proxy == null) { localTracker.connectTarget(this.connection.isSecure()); } else { localTracker.connectProxy(proxy, this.connection.isSecure()); } } /** * Tracks tunnelling of the connection to the target. * The tunnel has to be established outside by sending a CONNECT * request to the (last) proxy. * * @param secure true if the tunnel should be * considered secure, false otherwise * @param params the parameters for tunnelling the connection * * @throws IOException in case of a problem */ public void tunnelTarget(final boolean secure, final HttpParams params) throws IOException { Args.notNull(params, "HTTP parameters"); Asserts.notNull(this.tracker, "Route tracker"); Asserts.check(this.tracker.isConnected(), "Connection not open"); Asserts.check(!this.tracker.isTunnelled(), "Connection is already tunnelled"); this.connection.update(null, tracker.getTargetHost(), secure, params); this.tracker.tunnelTarget(secure); } /** * Tracks tunnelling of the connection to a chained proxy. * The tunnel has to be established outside by sending a CONNECT * request to the previous proxy. * * @param next the proxy to which the tunnel was established. * See {@link org.apache.http.conn.ManagedClientConnection#tunnelProxy * ManagedClientConnection.tunnelProxy} * for details. * @param secure true if the tunnel should be * considered secure, false otherwise * @param params the parameters for tunnelling the connection * * @throws IOException in case of a problem */ public void tunnelProxy(final HttpHost next, final boolean secure, final HttpParams params) throws IOException { Args.notNull(next, "Next proxy"); Args.notNull(params, "Parameters"); Asserts.notNull(this.tracker, "Route tracker"); Asserts.check(this.tracker.isConnected(), "Connection not open"); this.connection.update(null, next, secure, params); this.tracker.tunnelProxy(next, secure); } /** * Layers a protocol on top of an established tunnel. * * @param context the context for layering * @param params the parameters for layering * * @throws IOException in case of a problem */ public void layerProtocol(final HttpContext context, final HttpParams params) throws IOException { //@@@ is context allowed to be null? depends on operator? Args.notNull(params, "HTTP parameters"); Asserts.notNull(this.tracker, "Route tracker"); Asserts.check(this.tracker.isConnected(), "Connection not open"); Asserts.check(this.tracker.isTunnelled(), "Protocol layering without a tunnel not supported"); Asserts.check(!this.tracker.isLayered(), "Multiple protocol layering not supported"); // - collect the arguments // - call the operator // - update the tracking data // In this order, we can be sure that only a successful // layering on top of the connection will be tracked. final HttpHost target = tracker.getTargetHost(); connOperator.updateSecureConnection(this.connection, target, context, params); this.tracker.layerProtocol(this.connection.isSecure()); } /** * Shuts down the entry. * * If {@link #open(HttpRoute, HttpContext, HttpParams)} is in progress, * this will cause that open to possibly throw an {@link IOException}. */ protected void shutdownEntry() { tracker = null; state = null; } } ././@LongLink0100644 0000000 0000000 00000000174 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/BasicClientConnectionManager.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/BasicClien0100644 0000000 0000000 00000024476 12301751665 032350 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpClientConnection; import org.apache.http.annotation.GuardedBy; import org.apache.http.annotation.ThreadSafe; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.ClientConnectionOperator; import org.apache.http.conn.ClientConnectionRequest; import org.apache.http.conn.ManagedClientConnection; import org.apache.http.conn.OperatedClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.util.Args; import org.apache.http.util.Asserts; /** * A connection manager for a single connection. This connection manager maintains only one active * connection. Even though this class is fully thread-safe it ought to be used by one execution * thread only, as only one thread a time can lease the connection at a time. *

* This connection manager will make an effort to reuse the connection for subsequent requests * with the same {@link HttpRoute route}. It will, however, close the existing connection and * open it for the given route, if the route of the persistent connection does not match that * of the connection request. If the connection has been already been allocated * {@link IllegalStateException} is thrown. *

* This connection manager implementation should be used inside an EJB container instead of * {@link PoolingClientConnectionManager}. * * @since 4.2 * * @deprecated (4.3) use {@link BasicHttpClientConnectionManager}. */ @ThreadSafe @Deprecated public class BasicClientConnectionManager implements ClientConnectionManager { private final Log log = LogFactory.getLog(getClass()); private static final AtomicLong COUNTER = new AtomicLong(); /** The message to be logged on multiple allocation. */ public final static String MISUSE_MESSAGE = "Invalid use of BasicClientConnManager: connection still allocated.\n" + "Make sure to release the connection before allocating another one."; /** The schemes supported by this connection manager. */ private final SchemeRegistry schemeRegistry; /** The operator for opening and updating connections. */ private final ClientConnectionOperator connOperator; /** The one and only entry in this pool. */ @GuardedBy("this") private HttpPoolEntry poolEntry; /** The currently issued managed connection, if any. */ @GuardedBy("this") private ManagedClientConnectionImpl conn; /** Indicates whether this connection manager is shut down. */ @GuardedBy("this") private volatile boolean shutdown; /** * Creates a new simple connection manager. * * @param schreg the scheme registry */ public BasicClientConnectionManager(final SchemeRegistry schreg) { Args.notNull(schreg, "Scheme registry"); this.schemeRegistry = schreg; this.connOperator = createConnectionOperator(schreg); } public BasicClientConnectionManager() { this(SchemeRegistryFactory.createDefault()); } @Override protected void finalize() throws Throwable { try { shutdown(); } finally { // Make sure we call overridden method even if shutdown barfs super.finalize(); } } public SchemeRegistry getSchemeRegistry() { return this.schemeRegistry; } protected ClientConnectionOperator createConnectionOperator(final SchemeRegistry schreg) { return new DefaultClientConnectionOperator(schreg); } public final ClientConnectionRequest requestConnection( final HttpRoute route, final Object state) { return new ClientConnectionRequest() { public void abortRequest() { // Nothing to abort, since requests are immediate. } public ManagedClientConnection getConnection( final long timeout, final TimeUnit tunit) { return BasicClientConnectionManager.this.getConnection( route, state); } }; } private void assertNotShutdown() { Asserts.check(!this.shutdown, "Connection manager has been shut down"); } ManagedClientConnection getConnection(final HttpRoute route, final Object state) { Args.notNull(route, "Route"); synchronized (this) { assertNotShutdown(); if (this.log.isDebugEnabled()) { this.log.debug("Get connection for route " + route); } Asserts.check(this.conn == null, MISUSE_MESSAGE); if (this.poolEntry != null && !this.poolEntry.getPlannedRoute().equals(route)) { this.poolEntry.close(); this.poolEntry = null; } if (this.poolEntry == null) { final String id = Long.toString(COUNTER.getAndIncrement()); final OperatedClientConnection conn = this.connOperator.createConnection(); this.poolEntry = new HttpPoolEntry(this.log, id, route, conn, 0, TimeUnit.MILLISECONDS); } final long now = System.currentTimeMillis(); if (this.poolEntry.isExpired(now)) { this.poolEntry.close(); this.poolEntry.getTracker().reset(); } this.conn = new ManagedClientConnectionImpl(this, this.connOperator, this.poolEntry); return this.conn; } } private void shutdownConnection(final HttpClientConnection conn) { try { conn.shutdown(); } catch (final IOException iox) { if (this.log.isDebugEnabled()) { this.log.debug("I/O exception shutting down connection", iox); } } } public void releaseConnection(final ManagedClientConnection conn, final long keepalive, final TimeUnit tunit) { Args.check(conn instanceof ManagedClientConnectionImpl, "Connection class mismatch, " + "connection not obtained from this manager"); final ManagedClientConnectionImpl managedConn = (ManagedClientConnectionImpl) conn; synchronized (managedConn) { if (this.log.isDebugEnabled()) { this.log.debug("Releasing connection " + conn); } if (managedConn.getPoolEntry() == null) { return; // already released } final ClientConnectionManager manager = managedConn.getManager(); Asserts.check(manager == this, "Connection not obtained from this manager"); synchronized (this) { if (this.shutdown) { shutdownConnection(managedConn); return; } try { if (managedConn.isOpen() && !managedConn.isMarkedReusable()) { shutdownConnection(managedConn); } if (managedConn.isMarkedReusable()) { this.poolEntry.updateExpiry(keepalive, tunit != null ? tunit : TimeUnit.MILLISECONDS); if (this.log.isDebugEnabled()) { final String s; if (keepalive > 0) { s = "for " + keepalive + " " + tunit; } else { s = "indefinitely"; } this.log.debug("Connection can be kept alive " + s); } } } finally { managedConn.detach(); this.conn = null; if (this.poolEntry.isClosed()) { this.poolEntry = null; } } } } } public void closeExpiredConnections() { synchronized (this) { assertNotShutdown(); final long now = System.currentTimeMillis(); if (this.poolEntry != null && this.poolEntry.isExpired(now)) { this.poolEntry.close(); this.poolEntry.getTracker().reset(); } } } public void closeIdleConnections(final long idletime, final TimeUnit tunit) { Args.notNull(tunit, "Time unit"); synchronized (this) { assertNotShutdown(); long time = tunit.toMillis(idletime); if (time < 0) { time = 0; } final long deadline = System.currentTimeMillis() - time; if (this.poolEntry != null && this.poolEntry.getUpdated() <= deadline) { this.poolEntry.close(); this.poolEntry.getTracker().reset(); } } } public void shutdown() { synchronized (this) { this.shutdown = true; try { if (this.poolEntry != null) { this.poolEntry.close(); } } finally { this.poolEntry = null; this.conn = null; } } } } ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/DefaultClientConnection.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/DefaultCli0100644 0000000 0000000 00000023200 12301751665 032350 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.io.InterruptedIOException; import java.net.Socket; import java.util.HashMap; import java.util.Map; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseFactory; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.conn.OperatedClientConnection; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.impl.SocketHttpClientConnection; import org.apache.http.io.HttpMessageParser; import org.apache.http.io.SessionInputBuffer; import org.apache.http.io.SessionOutputBuffer; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** * Default implementation of an operated client connection. * * @since 4.0 * * @deprecated (4.3) use {@link ManagedHttpClientConnectionFactory}. */ @NotThreadSafe // connSecure, targetHost @Deprecated public class DefaultClientConnection extends SocketHttpClientConnection implements OperatedClientConnection, ManagedHttpClientConnection, HttpContext { private final Log log = LogFactory.getLog(getClass()); private final Log headerLog = LogFactory.getLog("org.apache.http.headers"); private final Log wireLog = LogFactory.getLog("org.apache.http.wire"); /** The unconnected socket */ private volatile Socket socket; /** The target host of this connection. */ private HttpHost targetHost; /** Whether this connection is secure. */ private boolean connSecure; /** True if this connection was shutdown. */ private volatile boolean shutdown; /** connection specific attributes */ private final Map attributes; public DefaultClientConnection() { super(); this.attributes = new HashMap(); } public String getId() { return null; } public final HttpHost getTargetHost() { return this.targetHost; } public final boolean isSecure() { return this.connSecure; } @Override public final Socket getSocket() { return this.socket; } public SSLSession getSSLSession() { if (this.socket instanceof SSLSocket) { return ((SSLSocket) this.socket).getSession(); } else { return null; } } public void opening(final Socket sock, final HttpHost target) throws IOException { assertNotOpen(); this.socket = sock; this.targetHost = target; // Check for shutdown after assigning socket, so that if (this.shutdown) { sock.close(); // allow this to throw... // ...but if it doesn't, explicitly throw one ourselves. throw new InterruptedIOException("Connection already shutdown"); } } public void openCompleted(final boolean secure, final HttpParams params) throws IOException { Args.notNull(params, "Parameters"); assertNotOpen(); this.connSecure = secure; bind(this.socket, params); } /** * Force-closes this connection. * If the connection is still in the process of being open (the method * {@link #opening opening} was already called but * {@link #openCompleted openCompleted} was not), the associated * socket that is being connected to a remote address will be closed. * That will interrupt a thread that is blocked on connecting * the socket. * If the connection is not yet open, this will prevent the connection * from being opened. * * @throws IOException in case of a problem */ @Override public void shutdown() throws IOException { shutdown = true; try { super.shutdown(); if (log.isDebugEnabled()) { log.debug("Connection " + this + " shut down"); } final Socket sock = this.socket; // copy volatile attribute if (sock != null) { sock.close(); } } catch (final IOException ex) { log.debug("I/O error shutting down connection", ex); } } @Override public void close() throws IOException { try { super.close(); if (log.isDebugEnabled()) { log.debug("Connection " + this + " closed"); } } catch (final IOException ex) { log.debug("I/O error closing connection", ex); } } @Override protected SessionInputBuffer createSessionInputBuffer( final Socket socket, final int buffersize, final HttpParams params) throws IOException { SessionInputBuffer inbuffer = super.createSessionInputBuffer( socket, buffersize > 0 ? buffersize : 8192, params); if (wireLog.isDebugEnabled()) { inbuffer = new LoggingSessionInputBuffer( inbuffer, new Wire(wireLog), HttpProtocolParams.getHttpElementCharset(params)); } return inbuffer; } @Override protected SessionOutputBuffer createSessionOutputBuffer( final Socket socket, final int buffersize, final HttpParams params) throws IOException { SessionOutputBuffer outbuffer = super.createSessionOutputBuffer( socket, buffersize > 0 ? buffersize : 8192, params); if (wireLog.isDebugEnabled()) { outbuffer = new LoggingSessionOutputBuffer( outbuffer, new Wire(wireLog), HttpProtocolParams.getHttpElementCharset(params)); } return outbuffer; } @Override protected HttpMessageParser createResponseParser( final SessionInputBuffer buffer, final HttpResponseFactory responseFactory, final HttpParams params) { // override in derived class to specify a line parser return new DefaultHttpResponseParser (buffer, null, responseFactory, params); } public void bind(final Socket socket) throws IOException { bind(socket, new BasicHttpParams()); } public void update(final Socket sock, final HttpHost target, final boolean secure, final HttpParams params) throws IOException { assertOpen(); Args.notNull(target, "Target host"); Args.notNull(params, "Parameters"); if (sock != null) { this.socket = sock; bind(sock, params); } targetHost = target; connSecure = secure; } @Override public HttpResponse receiveResponseHeader() throws HttpException, IOException { final HttpResponse response = super.receiveResponseHeader(); if (log.isDebugEnabled()) { log.debug("Receiving response: " + response.getStatusLine()); } if (headerLog.isDebugEnabled()) { headerLog.debug("<< " + response.getStatusLine().toString()); final Header[] headers = response.getAllHeaders(); for (final Header header : headers) { headerLog.debug("<< " + header.toString()); } } return response; } @Override public void sendRequestHeader(final HttpRequest request) throws HttpException, IOException { if (log.isDebugEnabled()) { log.debug("Sending request: " + request.getRequestLine()); } super.sendRequestHeader(request); if (headerLog.isDebugEnabled()) { headerLog.debug(">> " + request.getRequestLine().toString()); final Header[] headers = request.getAllHeaders(); for (final Header header : headers) { headerLog.debug(">> " + header.toString()); } } } public Object getAttribute(final String id) { return this.attributes.get(id); } public Object removeAttribute(final String id) { return this.attributes.remove(id); } public void setAttribute(final String id, final Object obj) { this.attributes.put(id, obj); } } ././@LongLink0100644 0000000 0000000 00000000177 12302131605 011631 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/DefaultClientConnectionOperator.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/DefaultCli0100644 0000000 0000000 00000024710 12301751665 032357 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.net.ConnectException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpHost; import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.protocol.ClientContext; import org.apache.http.conn.ClientConnectionOperator; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.DnsResolver; import org.apache.http.conn.HttpInetSocketAddress; import org.apache.http.conn.OperatedClientConnection; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeLayeredSocketFactory; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.scheme.SchemeSocketFactory; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.Asserts; /** * Default implementation of a {@link ClientConnectionOperator}. It uses a {@link SchemeRegistry} * to look up {@link SchemeSocketFactory} objects. *

* This connection operator is multihome network aware and will attempt to retry failed connects * against all known IP addresses sequentially until the connect is successful or all known * addresses fail to respond. Please note the same * {@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT} value will be used * for each connection attempt, so in the worst case the total elapsed time before timeout * can be CONNECTION_TIMEOUT * n where n is the number of IP addresses * of the given host. One can disable multihome support by overriding * the {@link #resolveHostname(String)} method and returning only one IP address for the given * host name. *

* The following parameters can be used to customize the behavior of this * class: *

    *
  • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_REUSEADDR}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
  • *
* * @since 4.0 * * @deprecated (4.3) use {@link PoolingHttpClientConnectionManager}. */ @Deprecated @ThreadSafe public class DefaultClientConnectionOperator implements ClientConnectionOperator { private final Log log = LogFactory.getLog(getClass()); /** The scheme registry for looking up socket factories. */ protected final SchemeRegistry schemeRegistry; // @ThreadSafe /** the custom-configured DNS lookup mechanism. */ protected final DnsResolver dnsResolver; /** * Creates a new client connection operator for the given scheme registry. * * @param schemes the scheme registry * * @since 4.2 */ public DefaultClientConnectionOperator(final SchemeRegistry schemes) { Args.notNull(schemes, "Scheme registry"); this.schemeRegistry = schemes; this.dnsResolver = new SystemDefaultDnsResolver(); } /** * Creates a new client connection operator for the given scheme registry * and the given custom DNS lookup mechanism. * * @param schemes * the scheme registry * @param dnsResolver * the custom DNS lookup mechanism */ public DefaultClientConnectionOperator(final SchemeRegistry schemes,final DnsResolver dnsResolver) { Args.notNull(schemes, "Scheme registry"); Args.notNull(dnsResolver, "DNS resolver"); this.schemeRegistry = schemes; this.dnsResolver = dnsResolver; } public OperatedClientConnection createConnection() { return new DefaultClientConnection(); } private SchemeRegistry getSchemeRegistry(final HttpContext context) { SchemeRegistry reg = (SchemeRegistry) context.getAttribute( ClientContext.SCHEME_REGISTRY); if (reg == null) { reg = this.schemeRegistry; } return reg; } public void openConnection( final OperatedClientConnection conn, final HttpHost target, final InetAddress local, final HttpContext context, final HttpParams params) throws IOException { Args.notNull(conn, "Connection"); Args.notNull(target, "Target host"); Args.notNull(params, "HTTP parameters"); Asserts.check(!conn.isOpen(), "Connection must not be open"); final SchemeRegistry registry = getSchemeRegistry(context); final Scheme schm = registry.getScheme(target.getSchemeName()); final SchemeSocketFactory sf = schm.getSchemeSocketFactory(); final InetAddress[] addresses = resolveHostname(target.getHostName()); final int port = schm.resolvePort(target.getPort()); for (int i = 0; i < addresses.length; i++) { final InetAddress address = addresses[i]; final boolean last = i == addresses.length - 1; Socket sock = sf.createSocket(params); conn.opening(sock, target); final InetSocketAddress remoteAddress = new HttpInetSocketAddress(target, address, port); InetSocketAddress localAddress = null; if (local != null) { localAddress = new InetSocketAddress(local, 0); } if (this.log.isDebugEnabled()) { this.log.debug("Connecting to " + remoteAddress); } try { final Socket connsock = sf.connectSocket(sock, remoteAddress, localAddress, params); if (sock != connsock) { sock = connsock; conn.opening(sock, target); } prepareSocket(sock, context, params); conn.openCompleted(sf.isSecure(sock), params); return; } catch (final ConnectException ex) { if (last) { throw ex; } } catch (final ConnectTimeoutException ex) { if (last) { throw ex; } } if (this.log.isDebugEnabled()) { this.log.debug("Connect to " + remoteAddress + " timed out. " + "Connection will be retried using another IP address"); } } } public void updateSecureConnection( final OperatedClientConnection conn, final HttpHost target, final HttpContext context, final HttpParams params) throws IOException { Args.notNull(conn, "Connection"); Args.notNull(target, "Target host"); Args.notNull(params, "Parameters"); Asserts.check(conn.isOpen(), "Connection must be open"); final SchemeRegistry registry = getSchemeRegistry(context); final Scheme schm = registry.getScheme(target.getSchemeName()); Asserts.check(schm.getSchemeSocketFactory() instanceof SchemeLayeredSocketFactory, "Socket factory must implement SchemeLayeredSocketFactory"); final SchemeLayeredSocketFactory lsf = (SchemeLayeredSocketFactory) schm.getSchemeSocketFactory(); final Socket sock = lsf.createLayeredSocket( conn.getSocket(), target.getHostName(), schm.resolvePort(target.getPort()), params); prepareSocket(sock, context, params); conn.update(sock, target, lsf.isSecure(sock), params); } /** * Performs standard initializations on a newly created socket. * * @param sock the socket to prepare * @param context the context for the connection * @param params the parameters from which to prepare the socket * * @throws IOException in case of an IO problem */ protected void prepareSocket( final Socket sock, final HttpContext context, final HttpParams params) throws IOException { sock.setTcpNoDelay(HttpConnectionParams.getTcpNoDelay(params)); sock.setSoTimeout(HttpConnectionParams.getSoTimeout(params)); final int linger = HttpConnectionParams.getLinger(params); if (linger >= 0) { sock.setSoLinger(linger > 0, linger); } } /** * Resolves the given host name to an array of corresponding IP addresses, based on the * configured name service on the provided DNS resolver. If one wasn't provided, the system * configuration is used. * * @param host host name to resolve * @return array of IP addresses * @exception UnknownHostException if no IP address for the host could be determined. * * @see DnsResolver * @see SystemDefaultDnsResolver * * @since 4.1 */ protected InetAddress[] resolveHostname(final String host) throws UnknownHostException { return dnsResolver.resolve(host); } } ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/DefaultHttpRoutePlanner.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/DefaultHtt0100644 0000000 0000000 00000010415 12301751664 032403 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.net.InetAddress; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.annotation.ThreadSafe; import org.apache.http.conn.params.ConnRouteParams; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.Asserts; /** * Default implementation of an {@link HttpRoutePlanner}. This implementation * is based on {@link org.apache.http.conn.params.ConnRoutePNames parameters}. * It will not make use of any Java system properties, nor of system or * browser proxy settings. *

* The following parameters can be used to customize the behavior of this * class: *

    *
  • {@link org.apache.http.conn.params.ConnRoutePNames#DEFAULT_PROXY}
  • *
  • {@link org.apache.http.conn.params.ConnRoutePNames#LOCAL_ADDRESS}
  • *
  • {@link org.apache.http.conn.params.ConnRoutePNames#FORCED_ROUTE}
  • *
* * @since 4.0 * * @deprecated (4.3) use {@link DefaultRoutePlanner} */ @ThreadSafe @Deprecated public class DefaultHttpRoutePlanner implements HttpRoutePlanner { /** The scheme registry. */ protected final SchemeRegistry schemeRegistry; // class is @ThreadSafe /** * Creates a new default route planner. * * @param schreg the scheme registry */ public DefaultHttpRoutePlanner(final SchemeRegistry schreg) { Args.notNull(schreg, "Scheme registry"); schemeRegistry = schreg; } public HttpRoute determineRoute(final HttpHost target, final HttpRequest request, final HttpContext context) throws HttpException { Args.notNull(request, "HTTP request"); // If we have a forced route, we can do without a target. HttpRoute route = ConnRouteParams.getForcedRoute(request.getParams()); if (route != null) { return route; } // If we get here, there is no forced route. // So we need a target to compute a route. Asserts.notNull(target, "Target host"); final InetAddress local = ConnRouteParams.getLocalAddress(request.getParams()); final HttpHost proxy = ConnRouteParams.getDefaultProxy(request.getParams()); final Scheme schm; try { schm = this.schemeRegistry.getScheme(target.getSchemeName()); } catch (final IllegalStateException ex) { throw new HttpException(ex.getMessage()); } // as it is typically used for TLS/SSL, we assume that // a layered scheme implies a secure connection final boolean secure = schm.isLayered(); if (proxy == null) { route = new HttpRoute(target, local, secure); } else { route = new HttpRoute(target, local, proxy, secure); } return route; } } ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/DefaultResponseParser.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/DefaultRes0100644 0000000 0000000 00000011434 12301751665 032400 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpException; import org.apache.http.HttpMessage; import org.apache.http.HttpResponseFactory; import org.apache.http.NoHttpResponseException; import org.apache.http.ProtocolException; import org.apache.http.StatusLine; import org.apache.http.annotation.ThreadSafe; import org.apache.http.impl.io.AbstractMessageParser; import org.apache.http.io.SessionInputBuffer; import org.apache.http.message.LineParser; import org.apache.http.message.ParserCursor; import org.apache.http.params.HttpParams; import org.apache.http.util.Args; import org.apache.http.util.CharArrayBuffer; /** * Default HTTP response parser implementation. *

* The following parameters can be used to customize the behavior of this * class: *

    *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
  • *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
  • *
  • {@link org.apache.http.conn.params.ConnConnectionPNames#MAX_STATUS_LINE_GARBAGE}
  • *
* * @since 4.0 * * @deprecated (4.2) use {@link DefaultHttpResponseParser} */ @Deprecated @ThreadSafe // no public methods public class DefaultResponseParser extends AbstractMessageParser { private final Log log = LogFactory.getLog(getClass()); private final HttpResponseFactory responseFactory; private final CharArrayBuffer lineBuf; private final int maxGarbageLines; public DefaultResponseParser( final SessionInputBuffer buffer, final LineParser parser, final HttpResponseFactory responseFactory, final HttpParams params) { super(buffer, parser, params); Args.notNull(responseFactory, "Response factory"); this.responseFactory = responseFactory; this.lineBuf = new CharArrayBuffer(128); this.maxGarbageLines = getMaxGarbageLines(params); } protected int getMaxGarbageLines(final HttpParams params) { return params.getIntParameter( org.apache.http.conn.params.ConnConnectionPNames.MAX_STATUS_LINE_GARBAGE, Integer.MAX_VALUE); } @Override protected HttpMessage parseHead( final SessionInputBuffer sessionBuffer) throws IOException, HttpException { //read out the HTTP status string int count = 0; ParserCursor cursor = null; do { // clear the buffer this.lineBuf.clear(); final int i = sessionBuffer.readLine(this.lineBuf); if (i == -1 && count == 0) { // The server just dropped connection on us throw new NoHttpResponseException("The target server failed to respond"); } cursor = new ParserCursor(0, this.lineBuf.length()); if (lineParser.hasProtocolVersion(this.lineBuf, cursor)) { // Got one break; } else if (i == -1 || count >= this.maxGarbageLines) { // Giving up throw new ProtocolException("The server failed to respond with a " + "valid HTTP response"); } if (this.log.isDebugEnabled()) { this.log.debug("Garbage in response: " + this.lineBuf.toString()); } count++; } while(true); //create the status line from the status string final StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor); return this.responseFactory.newHttpResponse(statusline, null); } } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/HttpConnPool.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/HttpConnPo0100644 0000000 0000000 00000006017 12301751664 032376 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.logging.Log; import org.apache.http.conn.ClientConnectionOperator; import org.apache.http.conn.OperatedClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.pool.AbstractConnPool; import org.apache.http.pool.ConnFactory; /** * @since 4.2 * * @deprecated (4.3) no longer used. */ @Deprecated class HttpConnPool extends AbstractConnPool { private static final AtomicLong COUNTER = new AtomicLong(); private final Log log; private final long timeToLive; private final TimeUnit tunit; public HttpConnPool(final Log log, final ClientConnectionOperator connOperator, final int defaultMaxPerRoute, final int maxTotal, final long timeToLive, final TimeUnit tunit) { super(new InternalConnFactory(connOperator), defaultMaxPerRoute, maxTotal); this.log = log; this.timeToLive = timeToLive; this.tunit = tunit; } @Override protected HttpPoolEntry createEntry(final HttpRoute route, final OperatedClientConnection conn) { final String id = Long.toString(COUNTER.getAndIncrement()); return new HttpPoolEntry(this.log, id, route, conn, this.timeToLive, this.tunit); } static class InternalConnFactory implements ConnFactory { private final ClientConnectionOperator connOperator; InternalConnFactory(final ClientConnectionOperator connOperator) { this.connOperator = connOperator; } public OperatedClientConnection create(final HttpRoute route) throws IOException { return connOperator.createConnection(); } } } ././@LongLink0100644 0000000 0000000 00000000155 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/HttpPoolEntry.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/HttpPoolEn0100644 0000000 0000000 00000005745 12301751665 032406 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.util.Date; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.http.conn.OperatedClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.RouteTracker; import org.apache.http.pool.PoolEntry; /** * @since 4.2 * * @deprecated (4.3) no longer used. */ @Deprecated class HttpPoolEntry extends PoolEntry { private final Log log; private final RouteTracker tracker; public HttpPoolEntry( final Log log, final String id, final HttpRoute route, final OperatedClientConnection conn, final long timeToLive, final TimeUnit tunit) { super(id, route, conn, timeToLive, tunit); this.log = log; this.tracker = new RouteTracker(route); } @Override public boolean isExpired(final long now) { final boolean expired = super.isExpired(now); if (expired && this.log.isDebugEnabled()) { this.log.debug("Connection " + this + " expired @ " + new Date(getExpiry())); } return expired; } RouteTracker getTracker() { return this.tracker; } HttpRoute getPlannedRoute() { return getRoute(); } HttpRoute getEffectiveRoute() { return this.tracker.toRoute(); } @Override public boolean isClosed() { final OperatedClientConnection conn = getConnection(); return !conn.isOpen(); } @Override public void close() { final OperatedClientConnection conn = getConnection(); try { conn.close(); } catch (final IOException ex) { this.log.debug("I/O error closing connection", ex); } } } ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/IdleConnectionHandler.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/IdleConnec0100644 0000000 0000000 00000014322 12301751665 032344 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpConnection; // Currently only used by AbstractConnPool /** * A helper class for connection managers to track idle connections. * *

This class is not synchronized.

* * @see org.apache.http.conn.ClientConnectionManager#closeIdleConnections * * @since 4.0 * * @deprecated (4.1) no longer used */ @Deprecated public class IdleConnectionHandler { private final Log log = LogFactory.getLog(getClass()); /** Holds connections and the time they were added. */ private final Map connectionToTimes; public IdleConnectionHandler() { super(); connectionToTimes = new HashMap(); } /** * Registers the given connection with this handler. The connection will be held until * {@link #remove} or {@link #closeIdleConnections} is called. * * @param connection the connection to add * * @see #remove */ public void add(final HttpConnection connection, final long validDuration, final TimeUnit unit) { final long timeAdded = System.currentTimeMillis(); if (log.isDebugEnabled()) { log.debug("Adding connection at: " + timeAdded); } connectionToTimes.put(connection, new TimeValues(timeAdded, validDuration, unit)); } /** * Removes the given connection from the list of connections to be closed when idle. * This will return true if the connection is still valid, and false * if the connection should be considered expired and not used. * * @param connection * @return True if the connection is still valid. */ public boolean remove(final HttpConnection connection) { final TimeValues times = connectionToTimes.remove(connection); if(times == null) { log.warn("Removing a connection that never existed!"); return true; } else { return System.currentTimeMillis() <= times.timeExpires; } } /** * Removes all connections referenced by this handler. */ public void removeAll() { this.connectionToTimes.clear(); } /** * Closes connections that have been idle for at least the given amount of time. * * @param idleTime the minimum idle time, in milliseconds, for connections to be closed */ public void closeIdleConnections(final long idleTime) { // the latest time for which connections will be closed final long idleTimeout = System.currentTimeMillis() - idleTime; if (log.isDebugEnabled()) { log.debug("Checking for connections, idle timeout: " + idleTimeout); } for (final Entry entry : connectionToTimes.entrySet()) { final HttpConnection conn = entry.getKey(); final TimeValues times = entry.getValue(); final long connectionTime = times.timeAdded; if (connectionTime <= idleTimeout) { if (log.isDebugEnabled()) { log.debug("Closing idle connection, connection time: " + connectionTime); } try { conn.close(); } catch (final IOException ex) { log.debug("I/O error closing connection", ex); } } } } public void closeExpiredConnections() { final long now = System.currentTimeMillis(); if (log.isDebugEnabled()) { log.debug("Checking for expired connections, now: " + now); } for (final Entry entry : connectionToTimes.entrySet()) { final HttpConnection conn = entry.getKey(); final TimeValues times = entry.getValue(); if(times.timeExpires <= now) { if (log.isDebugEnabled()) { log.debug("Closing connection, expired @: " + times.timeExpires); } try { conn.close(); } catch (final IOException ex) { log.debug("I/O error closing connection", ex); } } } } private static class TimeValues { private final long timeAdded; private final long timeExpires; /** * @param now The current time in milliseconds * @param validDuration The duration this connection is valid for * @param validUnit The unit of time the duration is specified in. */ TimeValues(final long now, final long validDuration, final TimeUnit validUnit) { this.timeAdded = now; if(validDuration > 0) { this.timeExpires = now + validUnit.toMillis(validDuration); } else { this.timeExpires = Long.MAX_VALUE; } } } } ././@LongLink0100644 0000000 0000000 00000000171 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/LoggingSessionInputBuffer.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/LoggingSes0100644 0000000 0000000 00000010473 12301751665 032405 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import org.apache.http.Consts; import org.apache.http.annotation.Immutable; import org.apache.http.io.EofSensor; import org.apache.http.io.HttpTransportMetrics; import org.apache.http.io.SessionInputBuffer; import org.apache.http.util.CharArrayBuffer; /** * Logs all data read to the wire LOG. * * @since 4.0 * * @deprecated (4.3) no longer used. */ @Immutable @Deprecated public class LoggingSessionInputBuffer implements SessionInputBuffer, EofSensor { /** Original session input buffer. */ private final SessionInputBuffer in; private final EofSensor eofSensor; /** The wire log to use for writing. */ private final Wire wire; private final String charset; /** * Create an instance that wraps the specified session input buffer. * @param in The session input buffer. * @param wire The wire log to use. * @param charset protocol charset, ASCII if null */ public LoggingSessionInputBuffer( final SessionInputBuffer in, final Wire wire, final String charset) { super(); this.in = in; this.eofSensor = in instanceof EofSensor ? (EofSensor) in : null; this.wire = wire; this.charset = charset != null ? charset : Consts.ASCII.name(); } public LoggingSessionInputBuffer(final SessionInputBuffer in, final Wire wire) { this(in, wire, null); } public boolean isDataAvailable(final int timeout) throws IOException { return this.in.isDataAvailable(timeout); } public int read(final byte[] b, final int off, final int len) throws IOException { final int l = this.in.read(b, off, len); if (this.wire.enabled() && l > 0) { this.wire.input(b, off, l); } return l; } public int read() throws IOException { final int l = this.in.read(); if (this.wire.enabled() && l != -1) { this.wire.input(l); } return l; } public int read(final byte[] b) throws IOException { final int l = this.in.read(b); if (this.wire.enabled() && l > 0) { this.wire.input(b, 0, l); } return l; } public String readLine() throws IOException { final String s = this.in.readLine(); if (this.wire.enabled() && s != null) { final String tmp = s + "\r\n"; this.wire.input(tmp.getBytes(this.charset)); } return s; } public int readLine(final CharArrayBuffer buffer) throws IOException { final int l = this.in.readLine(buffer); if (this.wire.enabled() && l >= 0) { final int pos = buffer.length() - l; final String s = new String(buffer.buffer(), pos, l); final String tmp = s + "\r\n"; this.wire.input(tmp.getBytes(this.charset)); } return l; } public HttpTransportMetrics getMetrics() { return this.in.getMetrics(); } public boolean isEof() { if (this.eofSensor != null) { return this.eofSensor.isEof(); } else { return false; } } } ././@LongLink0100644 0000000 0000000 00000000172 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/LoggingSessionOutputBuffer.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/LoggingSes0100644 0000000 0000000 00000007352 12301751665 032407 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import org.apache.http.Consts; import org.apache.http.annotation.Immutable; import org.apache.http.io.HttpTransportMetrics; import org.apache.http.io.SessionOutputBuffer; import org.apache.http.util.CharArrayBuffer; /** * Logs all data written to the wire LOG. * @since 4.0 * @deprecated (4.3) no longer used. */ @Immutable @Deprecated public class LoggingSessionOutputBuffer implements SessionOutputBuffer { /** Original data transmitter. */ private final SessionOutputBuffer out; /** The wire log to use. */ private final Wire wire; private final String charset; /** * Create an instance that wraps the specified session output buffer. * @param out The session output buffer. * @param wire The Wire log to use. * @param charset protocol charset, ASCII if null */ public LoggingSessionOutputBuffer( final SessionOutputBuffer out, final Wire wire, final String charset) { super(); this.out = out; this.wire = wire; this.charset = charset != null ? charset : Consts.ASCII.name(); } public LoggingSessionOutputBuffer(final SessionOutputBuffer out, final Wire wire) { this(out, wire, null); } public void write(final byte[] b, final int off, final int len) throws IOException { this.out.write(b, off, len); if (this.wire.enabled()) { this.wire.output(b, off, len); } } public void write(final int b) throws IOException { this.out.write(b); if (this.wire.enabled()) { this.wire.output(b); } } public void write(final byte[] b) throws IOException { this.out.write(b); if (this.wire.enabled()) { this.wire.output(b); } } public void flush() throws IOException { this.out.flush(); } public void writeLine(final CharArrayBuffer buffer) throws IOException { this.out.writeLine(buffer); if (this.wire.enabled()) { final String s = new String(buffer.buffer(), 0, buffer.length()); final String tmp = s + "\r\n"; this.wire.output(tmp.getBytes(this.charset)); } } public void writeLine(final String s) throws IOException { this.out.writeLine(s); if (this.wire.enabled()) { final String tmp = s + "\r\n"; this.wire.output(tmp.getBytes(this.charset)); } } public HttpTransportMetrics getMetrics() { return this.out.getMetrics(); } } ././@LongLink0100644 0000000 0000000 00000000173 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/ManagedClientConnectionImpl.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/ManagedCli0100644 0000000 0000000 00000035771 12301751665 032340 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.io.InterruptedIOException; import java.net.InetAddress; import java.net.Socket; import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import org.apache.http.HttpConnectionMetrics; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.ClientConnectionOperator; import org.apache.http.conn.ManagedClientConnection; import org.apache.http.conn.OperatedClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.RouteTracker; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.Asserts; /** * @since 4.2 * * @deprecated (4.3) use {@link ManagedHttpClientConnectionFactory}. */ @Deprecated @NotThreadSafe class ManagedClientConnectionImpl implements ManagedClientConnection { private final ClientConnectionManager manager; private final ClientConnectionOperator operator; private volatile HttpPoolEntry poolEntry; private volatile boolean reusable; private volatile long duration; ManagedClientConnectionImpl( final ClientConnectionManager manager, final ClientConnectionOperator operator, final HttpPoolEntry entry) { super(); Args.notNull(manager, "Connection manager"); Args.notNull(operator, "Connection operator"); Args.notNull(entry, "HTTP pool entry"); this.manager = manager; this.operator = operator; this.poolEntry = entry; this.reusable = false; this.duration = Long.MAX_VALUE; } public String getId() { return null; } HttpPoolEntry getPoolEntry() { return this.poolEntry; } HttpPoolEntry detach() { final HttpPoolEntry local = this.poolEntry; this.poolEntry = null; return local; } public ClientConnectionManager getManager() { return this.manager; } private OperatedClientConnection getConnection() { final HttpPoolEntry local = this.poolEntry; if (local == null) { return null; } return local.getConnection(); } private OperatedClientConnection ensureConnection() { final HttpPoolEntry local = this.poolEntry; if (local == null) { throw new ConnectionShutdownException(); } return local.getConnection(); } private HttpPoolEntry ensurePoolEntry() { final HttpPoolEntry local = this.poolEntry; if (local == null) { throw new ConnectionShutdownException(); } return local; } public void close() throws IOException { final HttpPoolEntry local = this.poolEntry; if (local != null) { final OperatedClientConnection conn = local.getConnection(); local.getTracker().reset(); conn.close(); } } public void shutdown() throws IOException { final HttpPoolEntry local = this.poolEntry; if (local != null) { final OperatedClientConnection conn = local.getConnection(); local.getTracker().reset(); conn.shutdown(); } } public boolean isOpen() { final OperatedClientConnection conn = getConnection(); if (conn != null) { return conn.isOpen(); } else { return false; } } public boolean isStale() { final OperatedClientConnection conn = getConnection(); if (conn != null) { return conn.isStale(); } else { return true; } } public void setSocketTimeout(final int timeout) { final OperatedClientConnection conn = ensureConnection(); conn.setSocketTimeout(timeout); } public int getSocketTimeout() { final OperatedClientConnection conn = ensureConnection(); return conn.getSocketTimeout(); } public HttpConnectionMetrics getMetrics() { final OperatedClientConnection conn = ensureConnection(); return conn.getMetrics(); } public void flush() throws IOException { final OperatedClientConnection conn = ensureConnection(); conn.flush(); } public boolean isResponseAvailable(final int timeout) throws IOException { final OperatedClientConnection conn = ensureConnection(); return conn.isResponseAvailable(timeout); } public void receiveResponseEntity( final HttpResponse response) throws HttpException, IOException { final OperatedClientConnection conn = ensureConnection(); conn.receiveResponseEntity(response); } public HttpResponse receiveResponseHeader() throws HttpException, IOException { final OperatedClientConnection conn = ensureConnection(); return conn.receiveResponseHeader(); } public void sendRequestEntity( final HttpEntityEnclosingRequest request) throws HttpException, IOException { final OperatedClientConnection conn = ensureConnection(); conn.sendRequestEntity(request); } public void sendRequestHeader( final HttpRequest request) throws HttpException, IOException { final OperatedClientConnection conn = ensureConnection(); conn.sendRequestHeader(request); } public InetAddress getLocalAddress() { final OperatedClientConnection conn = ensureConnection(); return conn.getLocalAddress(); } public int getLocalPort() { final OperatedClientConnection conn = ensureConnection(); return conn.getLocalPort(); } public InetAddress getRemoteAddress() { final OperatedClientConnection conn = ensureConnection(); return conn.getRemoteAddress(); } public int getRemotePort() { final OperatedClientConnection conn = ensureConnection(); return conn.getRemotePort(); } public boolean isSecure() { final OperatedClientConnection conn = ensureConnection(); return conn.isSecure(); } public void bind(final Socket socket) throws IOException { throw new UnsupportedOperationException(); } public Socket getSocket() { final OperatedClientConnection conn = ensureConnection(); return conn.getSocket(); } public SSLSession getSSLSession() { final OperatedClientConnection conn = ensureConnection(); SSLSession result = null; final Socket sock = conn.getSocket(); if (sock instanceof SSLSocket) { result = ((SSLSocket)sock).getSession(); } return result; } public Object getAttribute(final String id) { final OperatedClientConnection conn = ensureConnection(); if (conn instanceof HttpContext) { return ((HttpContext) conn).getAttribute(id); } else { return null; } } public Object removeAttribute(final String id) { final OperatedClientConnection conn = ensureConnection(); if (conn instanceof HttpContext) { return ((HttpContext) conn).removeAttribute(id); } else { return null; } } public void setAttribute(final String id, final Object obj) { final OperatedClientConnection conn = ensureConnection(); if (conn instanceof HttpContext) { ((HttpContext) conn).setAttribute(id, obj); } } public HttpRoute getRoute() { final HttpPoolEntry local = ensurePoolEntry(); return local.getEffectiveRoute(); } public void open( final HttpRoute route, final HttpContext context, final HttpParams params) throws IOException { Args.notNull(route, "Route"); Args.notNull(params, "HTTP parameters"); final OperatedClientConnection conn; synchronized (this) { if (this.poolEntry == null) { throw new ConnectionShutdownException(); } final RouteTracker tracker = this.poolEntry.getTracker(); Asserts.notNull(tracker, "Route tracker"); Asserts.check(!tracker.isConnected(), "Connection already open"); conn = this.poolEntry.getConnection(); } final HttpHost proxy = route.getProxyHost(); this.operator.openConnection( conn, (proxy != null) ? proxy : route.getTargetHost(), route.getLocalAddress(), context, params); synchronized (this) { if (this.poolEntry == null) { throw new InterruptedIOException(); } final RouteTracker tracker = this.poolEntry.getTracker(); if (proxy == null) { tracker.connectTarget(conn.isSecure()); } else { tracker.connectProxy(proxy, conn.isSecure()); } } } public void tunnelTarget( final boolean secure, final HttpParams params) throws IOException { Args.notNull(params, "HTTP parameters"); final HttpHost target; final OperatedClientConnection conn; synchronized (this) { if (this.poolEntry == null) { throw new ConnectionShutdownException(); } final RouteTracker tracker = this.poolEntry.getTracker(); Asserts.notNull(tracker, "Route tracker"); Asserts.check(tracker.isConnected(), "Connection not open"); Asserts.check(!tracker.isTunnelled(), "Connection is already tunnelled"); target = tracker.getTargetHost(); conn = this.poolEntry.getConnection(); } conn.update(null, target, secure, params); synchronized (this) { if (this.poolEntry == null) { throw new InterruptedIOException(); } final RouteTracker tracker = this.poolEntry.getTracker(); tracker.tunnelTarget(secure); } } public void tunnelProxy( final HttpHost next, final boolean secure, final HttpParams params) throws IOException { Args.notNull(next, "Next proxy"); Args.notNull(params, "HTTP parameters"); final OperatedClientConnection conn; synchronized (this) { if (this.poolEntry == null) { throw new ConnectionShutdownException(); } final RouteTracker tracker = this.poolEntry.getTracker(); Asserts.notNull(tracker, "Route tracker"); Asserts.check(tracker.isConnected(), "Connection not open"); conn = this.poolEntry.getConnection(); } conn.update(null, next, secure, params); synchronized (this) { if (this.poolEntry == null) { throw new InterruptedIOException(); } final RouteTracker tracker = this.poolEntry.getTracker(); tracker.tunnelProxy(next, secure); } } public void layerProtocol( final HttpContext context, final HttpParams params) throws IOException { Args.notNull(params, "HTTP parameters"); final HttpHost target; final OperatedClientConnection conn; synchronized (this) { if (this.poolEntry == null) { throw new ConnectionShutdownException(); } final RouteTracker tracker = this.poolEntry.getTracker(); Asserts.notNull(tracker, "Route tracker"); Asserts.check(tracker.isConnected(), "Connection not open"); Asserts.check(tracker.isTunnelled(), "Protocol layering without a tunnel not supported"); Asserts.check(!tracker.isLayered(), "Multiple protocol layering not supported"); target = tracker.getTargetHost(); conn = this.poolEntry.getConnection(); } this.operator.updateSecureConnection(conn, target, context, params); synchronized (this) { if (this.poolEntry == null) { throw new InterruptedIOException(); } final RouteTracker tracker = this.poolEntry.getTracker(); tracker.layerProtocol(conn.isSecure()); } } public Object getState() { final HttpPoolEntry local = ensurePoolEntry(); return local.getState(); } public void setState(final Object state) { final HttpPoolEntry local = ensurePoolEntry(); local.setState(state); } public void markReusable() { this.reusable = true; } public void unmarkReusable() { this.reusable = false; } public boolean isMarkedReusable() { return this.reusable; } public void setIdleDuration(final long duration, final TimeUnit unit) { if(duration > 0) { this.duration = unit.toMillis(duration); } else { this.duration = -1; } } public void releaseConnection() { synchronized (this) { if (this.poolEntry == null) { return; } this.manager.releaseConnection(this, this.duration, TimeUnit.MILLISECONDS); this.poolEntry = null; } } public void abortConnection() { synchronized (this) { if (this.poolEntry == null) { return; } this.reusable = false; final OperatedClientConnection conn = this.poolEntry.getConnection(); try { conn.shutdown(); } catch (final IOException ignore) { } this.manager.releaseConnection(this, this.duration, TimeUnit.MILLISECONDS); this.poolEntry = null; } } } ././@LongLink0100644 0000000 0000000 00000000176 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/PoolingClientConnectionManager.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/PoolingCli0100644 0000000 0000000 00000030744 12301751665 032406 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.annotation.ThreadSafe; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.ClientConnectionOperator; import org.apache.http.conn.ClientConnectionRequest; import org.apache.http.conn.ConnectionPoolTimeoutException; import org.apache.http.conn.DnsResolver; import org.apache.http.conn.ManagedClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.pool.ConnPoolControl; import org.apache.http.pool.PoolStats; import org.apache.http.util.Args; import org.apache.http.util.Asserts; /** * Manages a pool of {@link org.apache.http.conn.OperatedClientConnection} * and is able to service connection requests from multiple execution threads. * Connections are pooled on a per route basis. A request for a route which * already the manager has persistent connections for available in the pool * will be services by leasing a connection from the pool rather than * creating a brand new connection. *

* PoolingConnectionManager maintains a maximum limit of connection on * a per route basis and in total. Per default this implementation will * create no more than than 2 concurrent connections per given route * and no more 20 connections in total. For many real-world applications * these limits may prove too constraining, especially if they use HTTP * as a transport protocol for their services. Connection limits, however, * can be adjusted using HTTP parameters. * * @since 4.2 * * @deprecated (4.3) use {@link PoolingHttpClientConnectionManager}. */ @Deprecated @ThreadSafe public class PoolingClientConnectionManager implements ClientConnectionManager, ConnPoolControl { private final Log log = LogFactory.getLog(getClass()); private final SchemeRegistry schemeRegistry; private final HttpConnPool pool; private final ClientConnectionOperator operator; /** the custom-configured DNS lookup mechanism. */ private final DnsResolver dnsResolver; public PoolingClientConnectionManager(final SchemeRegistry schreg) { this(schreg, -1, TimeUnit.MILLISECONDS); } public PoolingClientConnectionManager(final SchemeRegistry schreg,final DnsResolver dnsResolver) { this(schreg, -1, TimeUnit.MILLISECONDS,dnsResolver); } public PoolingClientConnectionManager() { this(SchemeRegistryFactory.createDefault()); } public PoolingClientConnectionManager( final SchemeRegistry schemeRegistry, final long timeToLive, final TimeUnit tunit) { this(schemeRegistry, timeToLive, tunit, new SystemDefaultDnsResolver()); } public PoolingClientConnectionManager(final SchemeRegistry schemeRegistry, final long timeToLive, final TimeUnit tunit, final DnsResolver dnsResolver) { super(); Args.notNull(schemeRegistry, "Scheme registry"); Args.notNull(dnsResolver, "DNS resolver"); this.schemeRegistry = schemeRegistry; this.dnsResolver = dnsResolver; this.operator = createConnectionOperator(schemeRegistry); this.pool = new HttpConnPool(this.log, this.operator, 2, 20, timeToLive, tunit); } @Override protected void finalize() throws Throwable { try { shutdown(); } finally { super.finalize(); } } /** * Hook for creating the connection operator. * It is called by the constructor. * Derived classes can override this method to change the * instantiation of the operator. * The default implementation here instantiates * {@link DefaultClientConnectionOperator DefaultClientConnectionOperator}. * * @param schreg the scheme registry. * * @return the connection operator to use */ protected ClientConnectionOperator createConnectionOperator(final SchemeRegistry schreg) { return new DefaultClientConnectionOperator(schreg, this.dnsResolver); } public SchemeRegistry getSchemeRegistry() { return this.schemeRegistry; } private String format(final HttpRoute route, final Object state) { final StringBuilder buf = new StringBuilder(); buf.append("[route: ").append(route).append("]"); if (state != null) { buf.append("[state: ").append(state).append("]"); } return buf.toString(); } private String formatStats(final HttpRoute route) { final StringBuilder buf = new StringBuilder(); final PoolStats totals = this.pool.getTotalStats(); final PoolStats stats = this.pool.getStats(route); buf.append("[total kept alive: ").append(totals.getAvailable()).append("; "); buf.append("route allocated: ").append(stats.getLeased() + stats.getAvailable()); buf.append(" of ").append(stats.getMax()).append("; "); buf.append("total allocated: ").append(totals.getLeased() + totals.getAvailable()); buf.append(" of ").append(totals.getMax()).append("]"); return buf.toString(); } private String format(final HttpPoolEntry entry) { final StringBuilder buf = new StringBuilder(); buf.append("[id: ").append(entry.getId()).append("]"); buf.append("[route: ").append(entry.getRoute()).append("]"); final Object state = entry.getState(); if (state != null) { buf.append("[state: ").append(state).append("]"); } return buf.toString(); } public ClientConnectionRequest requestConnection( final HttpRoute route, final Object state) { Args.notNull(route, "HTTP route"); if (this.log.isDebugEnabled()) { this.log.debug("Connection request: " + format(route, state) + formatStats(route)); } final Future future = this.pool.lease(route, state); return new ClientConnectionRequest() { public void abortRequest() { future.cancel(true); } public ManagedClientConnection getConnection( final long timeout, final TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException { return leaseConnection(future, timeout, tunit); } }; } ManagedClientConnection leaseConnection( final Future future, final long timeout, final TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException { final HttpPoolEntry entry; try { entry = future.get(timeout, tunit); if (entry == null || future.isCancelled()) { throw new InterruptedException(); } Asserts.check(entry.getConnection() != null, "Pool entry with no connection"); if (this.log.isDebugEnabled()) { this.log.debug("Connection leased: " + format(entry) + formatStats(entry.getRoute())); } return new ManagedClientConnectionImpl(this, this.operator, entry); } catch (final ExecutionException ex) { Throwable cause = ex.getCause(); if (cause == null) { cause = ex; } this.log.error("Unexpected exception leasing connection from pool", cause); // Should never happen throw new InterruptedException(); } catch (final TimeoutException ex) { throw new ConnectionPoolTimeoutException("Timeout waiting for connection from pool"); } } public void releaseConnection( final ManagedClientConnection conn, final long keepalive, final TimeUnit tunit) { Args.check(conn instanceof ManagedClientConnectionImpl, "Connection class mismatch, " + "connection not obtained from this manager"); final ManagedClientConnectionImpl managedConn = (ManagedClientConnectionImpl) conn; Asserts.check(managedConn.getManager() == this, "Connection not obtained from this manager"); synchronized (managedConn) { final HttpPoolEntry entry = managedConn.detach(); if (entry == null) { return; } try { if (managedConn.isOpen() && !managedConn.isMarkedReusable()) { try { managedConn.shutdown(); } catch (final IOException iox) { if (this.log.isDebugEnabled()) { this.log.debug("I/O exception shutting down released connection", iox); } } } // Only reusable connections can be kept alive if (managedConn.isMarkedReusable()) { entry.updateExpiry(keepalive, tunit != null ? tunit : TimeUnit.MILLISECONDS); if (this.log.isDebugEnabled()) { final String s; if (keepalive > 0) { s = "for " + keepalive + " " + tunit; } else { s = "indefinitely"; } this.log.debug("Connection " + format(entry) + " can be kept alive " + s); } } } finally { this.pool.release(entry, managedConn.isMarkedReusable()); } if (this.log.isDebugEnabled()) { this.log.debug("Connection released: " + format(entry) + formatStats(entry.getRoute())); } } } public void shutdown() { this.log.debug("Connection manager is shutting down"); try { this.pool.shutdown(); } catch (final IOException ex) { this.log.debug("I/O exception shutting down connection manager", ex); } this.log.debug("Connection manager shut down"); } public void closeIdleConnections(final long idleTimeout, final TimeUnit tunit) { if (this.log.isDebugEnabled()) { this.log.debug("Closing connections idle longer than " + idleTimeout + " " + tunit); } this.pool.closeIdle(idleTimeout, tunit); } public void closeExpiredConnections() { this.log.debug("Closing expired connections"); this.pool.closeExpired(); } public int getMaxTotal() { return this.pool.getMaxTotal(); } public void setMaxTotal(final int max) { this.pool.setMaxTotal(max); } public int getDefaultMaxPerRoute() { return this.pool.getDefaultMaxPerRoute(); } public void setDefaultMaxPerRoute(final int max) { this.pool.setDefaultMaxPerRoute(max); } public int getMaxPerRoute(final HttpRoute route) { return this.pool.getMaxPerRoute(route); } public void setMaxPerRoute(final HttpRoute route, final int max) { this.pool.setMaxPerRoute(route, max); } public PoolStats getTotalStats() { return this.pool.getTotalStats(); } public PoolStats getStats(final HttpRoute route) { return this.pool.getStats(route); } } ././@LongLink0100644 0000000 0000000 00000000171 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/ProxySelectorRoutePlanner.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/ProxySelec0100644 0000000 0000000 00000023263 12301751665 032442 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.ProxySelector; import java.net.URI; import java.net.URISyntaxException; import java.util.List; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.conn.params.ConnRouteParams; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.Asserts; /** * Default implementation of an {@link HttpRoutePlanner}. * This implementation is based on {@link java.net.ProxySelector}. * By default, it will pick up the proxy settings of the JVM, either * from system properties or from the browser running the application. * Additionally, it interprets some * {@link org.apache.http.conn.params.ConnRoutePNames parameters}, * though not the {@link * org.apache.http.conn.params.ConnRoutePNames#DEFAULT_PROXY DEFAULT_PROXY}. *

* The following parameters can be used to customize the behavior of this * class: *

    *
  • {@link org.apache.http.conn.params.ConnRoutePNames#LOCAL_ADDRESS}
  • *
  • {@link org.apache.http.conn.params.ConnRoutePNames#FORCED_ROUTE}
  • *
* * @since 4.0 * * @deprecated (4.3) use {@link SystemDefaultRoutePlanner} */ @NotThreadSafe // e.g [gs]etProxySelector() @Deprecated public class ProxySelectorRoutePlanner implements HttpRoutePlanner { /** The scheme registry. */ protected final SchemeRegistry schemeRegistry; // @ThreadSafe /** The proxy selector to use, or null for system default. */ protected ProxySelector proxySelector; /** * Creates a new proxy selector route planner. * * @param schreg the scheme registry * @param prosel the proxy selector, or * null for the system default */ public ProxySelectorRoutePlanner(final SchemeRegistry schreg, final ProxySelector prosel) { Args.notNull(schreg, "SchemeRegistry"); schemeRegistry = schreg; proxySelector = prosel; } /** * Obtains the proxy selector to use. * * @return the proxy selector, or null for the system default */ public ProxySelector getProxySelector() { return this.proxySelector; } /** * Sets the proxy selector to use. * * @param prosel the proxy selector, or * null to use the system default */ public void setProxySelector(final ProxySelector prosel) { this.proxySelector = prosel; } public HttpRoute determineRoute(final HttpHost target, final HttpRequest request, final HttpContext context) throws HttpException { Args.notNull(request, "HTTP request"); // If we have a forced route, we can do without a target. HttpRoute route = ConnRouteParams.getForcedRoute(request.getParams()); if (route != null) { return route; } // If we get here, there is no forced route. // So we need a target to compute a route. Asserts.notNull(target, "Target host"); final InetAddress local = ConnRouteParams.getLocalAddress(request.getParams()); final HttpHost proxy = determineProxy(target, request, context); final Scheme schm = this.schemeRegistry.getScheme(target.getSchemeName()); // as it is typically used for TLS/SSL, we assume that // a layered scheme implies a secure connection final boolean secure = schm.isLayered(); if (proxy == null) { route = new HttpRoute(target, local, secure); } else { route = new HttpRoute(target, local, proxy, secure); } return route; } /** * Determines a proxy for the given target. * * @param target the planned target, never null * @param request the request to be sent, never null * @param context the context, or null * * @return the proxy to use, or null for a direct route * * @throws HttpException * in case of system proxy settings that cannot be handled */ protected HttpHost determineProxy(final HttpHost target, final HttpRequest request, final HttpContext context) throws HttpException { // the proxy selector can be 'unset', so we better deal with null here ProxySelector psel = this.proxySelector; if (psel == null) { psel = ProxySelector.getDefault(); } if (psel == null) { return null; } URI targetURI = null; try { targetURI = new URI(target.toURI()); } catch (final URISyntaxException usx) { throw new HttpException ("Cannot convert host to URI: " + target, usx); } final List proxies = psel.select(targetURI); final Proxy p = chooseProxy(proxies, target, request, context); HttpHost result = null; if (p.type() == Proxy.Type.HTTP) { // convert the socket address to an HttpHost if (!(p.address() instanceof InetSocketAddress)) { throw new HttpException ("Unable to handle non-Inet proxy address: "+p.address()); } final InetSocketAddress isa = (InetSocketAddress) p.address(); // assume default scheme (http) result = new HttpHost(getHost(isa), isa.getPort()); } return result; } /** * Obtains a host from an {@link InetSocketAddress}. * * @param isa the socket address * * @return a host string, either as a symbolic name or * as a literal IP address string *
* (TODO: determine format for IPv6 addresses, with or without [brackets]) */ protected String getHost(final InetSocketAddress isa) { //@@@ Will this work with literal IPv6 addresses, or do we //@@@ need to wrap these in [] for the string representation? //@@@ Having it in this method at least allows for easy workarounds. return isa.isUnresolved() ? isa.getHostName() : isa.getAddress().getHostAddress(); } /** * Chooses a proxy from a list of available proxies. * The default implementation just picks the first non-SOCKS proxy * from the list. If there are only SOCKS proxies, * {@link Proxy#NO_PROXY Proxy.NO_PROXY} is returned. * Derived classes may implement more advanced strategies, * such as proxy rotation if there are multiple options. * * @param proxies the list of proxies to choose from, * never null or empty * @param target the planned target, never null * @param request the request to be sent, never null * @param context the context, or null * * @return a proxy type */ protected Proxy chooseProxy(final List proxies, final HttpHost target, final HttpRequest request, final HttpContext context) { Args.notEmpty(proxies, "List of proxies"); Proxy result = null; // check the list for one we can use for (int i=0; (result == null) && (i < proxies.size()); i++) { final Proxy p = proxies.get(i); switch (p.type()) { case DIRECT: case HTTP: result = p; break; case SOCKS: // SOCKS hosts are not handled on the route level. // The socket may make use of the SOCKS host though. break; } } if (result == null) { //@@@ log as warning or info that only a socks proxy is available? // result can only be null if all proxies are socks proxies // socks proxies are not handled on the route planning level result = Proxy.NO_PROXY; } return result; } } ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/SchemeRegistryFactory.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/SchemeRegi0100644 0000000 0000000 00000006630 12301751664 032356 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import org.apache.http.annotation.ThreadSafe; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; /** * @since 4.1 * * @deprecated (4.3) use {@link org.apache.http.impl.client.HttpClientBuilder}. */ @ThreadSafe @Deprecated public final class SchemeRegistryFactory { /** * Initializes default scheme registry based on JSSE defaults. System properties will * not be taken into consideration. */ public static SchemeRegistry createDefault() { final SchemeRegistry registry = new SchemeRegistry(); registry.register( new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); registry.register( new Scheme("https", 443, SSLSocketFactory.getSocketFactory())); return registry; } /** * Initializes default scheme registry using system properties as described in * * "JavaTM Secure Socket Extension (JSSE) Reference Guide for the JavaTM 2 Platform * Standard Edition 5 *

* The following system properties are taken into account by this method: *

    *
  • ssl.TrustManagerFactory.algorithm
  • *
  • javax.net.ssl.trustStoreType
  • *
  • javax.net.ssl.trustStore
  • *
  • javax.net.ssl.trustStoreProvider
  • *
  • javax.net.ssl.trustStorePassword
  • *
  • java.home
  • *
  • ssl.KeyManagerFactory.algorithm
  • *
  • javax.net.ssl.keyStoreType
  • *
  • javax.net.ssl.keyStore
  • *
  • javax.net.ssl.keyStoreProvider
  • *
  • javax.net.ssl.keyStorePassword
  • *
*

* * @since 4.2 */ public static SchemeRegistry createSystemDefault() { final SchemeRegistry registry = new SchemeRegistry(); registry.register( new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); registry.register( new Scheme("https", 443, SSLSocketFactory.getSystemSocketFactory())); return registry; } } ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/SingleClientConnManager.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/SingleClie0100644 0000000 0000000 00000034343 12301751665 032364 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.IOException; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.annotation.GuardedBy; import org.apache.http.annotation.ThreadSafe; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.ClientConnectionOperator; import org.apache.http.conn.ClientConnectionRequest; import org.apache.http.conn.ManagedClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.RouteTracker; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.params.HttpParams; import org.apache.http.util.Args; import org.apache.http.util.Asserts; /** * A connection manager for a single connection. This connection manager * maintains only one active connection at a time. Even though this class * is thread-safe it ought to be used by one execution thread only. *

* SingleClientConnManager will make an effort to reuse the connection * for subsequent requests with the same {@link HttpRoute route}. * It will, however, close the existing connection and open it * for the given route, if the route of the persistent connection does * not match that of the connection request. If the connection has been * already been allocated {@link IllegalStateException} is thrown. * * @since 4.0 * * @deprecated (4.2) use {@link BasicClientConnectionManager} */ @ThreadSafe @Deprecated public class SingleClientConnManager implements ClientConnectionManager { private final Log log = LogFactory.getLog(getClass()); /** The message to be logged on multiple allocation. */ public final static String MISUSE_MESSAGE = "Invalid use of SingleClientConnManager: connection still allocated.\n" + "Make sure to release the connection before allocating another one."; /** The schemes supported by this connection manager. */ protected final SchemeRegistry schemeRegistry; /** The operator for opening and updating connections. */ protected final ClientConnectionOperator connOperator; /** Whether the connection should be shut down on release. */ protected final boolean alwaysShutDown; /** The one and only entry in this pool. */ @GuardedBy("this") protected volatile PoolEntry uniquePoolEntry; /** The currently issued managed connection, if any. */ @GuardedBy("this") protected volatile ConnAdapter managedConn; /** The time of the last connection release, or -1. */ @GuardedBy("this") protected volatile long lastReleaseTime; /** The time the last released connection expires and shouldn't be reused. */ @GuardedBy("this") protected volatile long connectionExpiresTime; /** Indicates whether this connection manager is shut down. */ protected volatile boolean isShutDown; /** * Creates a new simple connection manager. * * @param params the parameters for this manager * @param schreg the scheme registry * * @deprecated (4.1) use {@link SingleClientConnManager#SingleClientConnManager(SchemeRegistry)} */ @Deprecated public SingleClientConnManager(final HttpParams params, final SchemeRegistry schreg) { this(schreg); } /** * Creates a new simple connection manager. * * @param schreg the scheme registry */ public SingleClientConnManager(final SchemeRegistry schreg) { Args.notNull(schreg, "Scheme registry"); this.schemeRegistry = schreg; this.connOperator = createConnectionOperator(schreg); this.uniquePoolEntry = new PoolEntry(); this.managedConn = null; this.lastReleaseTime = -1L; this.alwaysShutDown = false; //@@@ from params? as argument? this.isShutDown = false; } /** * @since 4.1 */ public SingleClientConnManager() { this(SchemeRegistryFactory.createDefault()); } @Override protected void finalize() throws Throwable { try { shutdown(); } finally { // Make sure we call overridden method even if shutdown barfs super.finalize(); } } public SchemeRegistry getSchemeRegistry() { return this.schemeRegistry; } /** * Hook for creating the connection operator. * It is called by the constructor. * Derived classes can override this method to change the * instantiation of the operator. * The default implementation here instantiates * {@link DefaultClientConnectionOperator DefaultClientConnectionOperator}. * * @param schreg the scheme registry to use, or null * * @return the connection operator to use */ protected ClientConnectionOperator createConnectionOperator(final SchemeRegistry schreg) { return new DefaultClientConnectionOperator(schreg); } /** * Asserts that this manager is not shut down. * * @throws IllegalStateException if this manager is shut down */ protected final void assertStillUp() throws IllegalStateException { Asserts.check(!this.isShutDown, "Manager is shut down"); } public final ClientConnectionRequest requestConnection( final HttpRoute route, final Object state) { return new ClientConnectionRequest() { public void abortRequest() { // Nothing to abort, since requests are immediate. } public ManagedClientConnection getConnection( final long timeout, final TimeUnit tunit) { return SingleClientConnManager.this.getConnection( route, state); } }; } /** * Obtains a connection. * * @param route where the connection should point to * * @return a connection that can be used to communicate * along the given route */ public ManagedClientConnection getConnection(final HttpRoute route, final Object state) { Args.notNull(route, "Route"); assertStillUp(); if (log.isDebugEnabled()) { log.debug("Get connection for route " + route); } synchronized (this) { Asserts.check(managedConn == null, MISUSE_MESSAGE); // check re-usability of the connection boolean recreate = false; boolean shutdown = false; // Kill the connection if it expired. closeExpiredConnections(); if (uniquePoolEntry.connection.isOpen()) { final RouteTracker tracker = uniquePoolEntry.tracker; shutdown = (tracker == null || // can happen if method is aborted !tracker.toRoute().equals(route)); } else { // If the connection is not open, create a new PoolEntry, // as the connection may have been marked not reusable, // due to aborts -- and the PoolEntry should not be reused // either. There's no harm in recreating an entry if // the connection is closed. recreate = true; } if (shutdown) { recreate = true; try { uniquePoolEntry.shutdown(); } catch (final IOException iox) { log.debug("Problem shutting down connection.", iox); } } if (recreate) { uniquePoolEntry = new PoolEntry(); } managedConn = new ConnAdapter(uniquePoolEntry, route); return managedConn; } } public void releaseConnection( final ManagedClientConnection conn, final long validDuration, final TimeUnit timeUnit) { Args.check(conn instanceof ConnAdapter, "Connection class mismatch, " + "connection not obtained from this manager"); assertStillUp(); if (log.isDebugEnabled()) { log.debug("Releasing connection " + conn); } final ConnAdapter sca = (ConnAdapter) conn; synchronized (sca) { if (sca.poolEntry == null) { return; // already released } final ClientConnectionManager manager = sca.getManager(); Asserts.check(manager == this, "Connection not obtained from this manager"); try { // make sure that the response has been read completely if (sca.isOpen() && (this.alwaysShutDown || !sca.isMarkedReusable()) ) { if (log.isDebugEnabled()) { log.debug ("Released connection open but not reusable."); } // make sure this connection will not be re-used // we might have gotten here because of a shutdown trigger // shutdown of the adapter also clears the tracked route sca.shutdown(); } } catch (final IOException iox) { if (log.isDebugEnabled()) { log.debug("Exception shutting down released connection.", iox); } } finally { sca.detach(); synchronized (this) { managedConn = null; lastReleaseTime = System.currentTimeMillis(); if(validDuration > 0) { connectionExpiresTime = timeUnit.toMillis(validDuration) + lastReleaseTime; } else { connectionExpiresTime = Long.MAX_VALUE; } } } } } public void closeExpiredConnections() { final long time = connectionExpiresTime; if (System.currentTimeMillis() >= time) { closeIdleConnections(0, TimeUnit.MILLISECONDS); } } public void closeIdleConnections(final long idletime, final TimeUnit tunit) { assertStillUp(); // idletime can be 0 or negative, no problem there Args.notNull(tunit, "Time unit"); synchronized (this) { if ((managedConn == null) && uniquePoolEntry.connection.isOpen()) { final long cutoff = System.currentTimeMillis() - tunit.toMillis(idletime); if (lastReleaseTime <= cutoff) { try { uniquePoolEntry.close(); } catch (final IOException iox) { // ignore log.debug("Problem closing idle connection.", iox); } } } } } public void shutdown() { this.isShutDown = true; synchronized (this) { try { if (uniquePoolEntry != null) { uniquePoolEntry.shutdown(); } } catch (final IOException iox) { // ignore log.debug("Problem while shutting down manager.", iox); } finally { uniquePoolEntry = null; managedConn = null; } } } protected void revokeConnection() { final ConnAdapter conn = managedConn; if (conn == null) { return; } conn.detach(); synchronized (this) { try { uniquePoolEntry.shutdown(); } catch (final IOException iox) { // ignore log.debug("Problem while shutting down connection.", iox); } } } /** * The pool entry for this connection manager. */ protected class PoolEntry extends AbstractPoolEntry { /** * Creates a new pool entry. * */ protected PoolEntry() { super(SingleClientConnManager.this.connOperator, null); } /** * Closes the connection in this pool entry. */ protected void close() throws IOException { shutdownEntry(); if (connection.isOpen()) { connection.close(); } } /** * Shuts down the connection in this pool entry. */ protected void shutdown() throws IOException { shutdownEntry(); if (connection.isOpen()) { connection.shutdown(); } } } /** * The connection adapter used by this manager. */ protected class ConnAdapter extends AbstractPooledConnAdapter { /** * Creates a new connection adapter. * * @param entry the pool entry for the connection being wrapped * @param route the planned route for this connection */ protected ConnAdapter(final PoolEntry entry, final HttpRoute route) { super(SingleClientConnManager.this, entry); markReusable(); entry.route = route; } } } httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/0040755 0000000 0000000 00000000000 12301751664 031527 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000166 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/AbstractConnPool.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/Abst0100644 0000000 0000000 00000016673 12301751664 032355 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn.tsccm; import java.io.IOException; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.annotation.GuardedBy; import org.apache.http.conn.ConnectionPoolTimeoutException; import org.apache.http.conn.OperatedClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.impl.conn.IdleConnectionHandler; import org.apache.http.util.Args; /** * An abstract connection pool. * It is used by the {@link ThreadSafeClientConnManager}. * The abstract pool includes a {@link #poolLock}, which is used to * synchronize access to the internal pool datastructures. * Don't use synchronized for that purpose! * * @since 4.0 * * @deprecated (4.2) use {@link org.apache.http.pool.AbstractConnPool} */ @Deprecated public abstract class AbstractConnPool { private final Log log; /** * The global lock for this pool. */ protected final Lock poolLock; /** References to issued connections */ @GuardedBy("poolLock") protected Set leasedConnections; /** The current total number of connections. */ @GuardedBy("poolLock") protected int numConnections; /** Indicates whether this pool is shut down. */ protected volatile boolean isShutDown; protected Set issuedConnections; protected ReferenceQueue refQueue; protected IdleConnectionHandler idleConnHandler; /** * Creates a new connection pool. */ protected AbstractConnPool() { super(); this.log = LogFactory.getLog(getClass()); this.leasedConnections = new HashSet(); this.idleConnHandler = new IdleConnectionHandler(); this.poolLock = new ReentrantLock(); } public void enableConnectionGC() throws IllegalStateException { } /** * Obtains a pool entry with a connection within the given timeout. * * @param route the route for which to get the connection * @param timeout the timeout, 0 or negative for no timeout * @param tunit the unit for the timeout, * may be null only if there is no timeout * * @return pool entry holding a connection for the route * * @throws ConnectionPoolTimeoutException * if the timeout expired * @throws InterruptedException * if the calling thread was interrupted */ public final BasicPoolEntry getEntry( final HttpRoute route, final Object state, final long timeout, final TimeUnit tunit) throws ConnectionPoolTimeoutException, InterruptedException { return requestPoolEntry(route, state).getPoolEntry(timeout, tunit); } /** * Returns a new {@link PoolEntryRequest}, from which a {@link BasicPoolEntry} * can be obtained, or the request can be aborted. */ public abstract PoolEntryRequest requestPoolEntry(HttpRoute route, Object state); /** * Returns an entry into the pool. * The connection of the entry is expected to be in a suitable state, * either open and re-usable, or closed. The pool will not make any * attempt to determine whether it can be re-used or not. * * @param entry the entry for the connection to release * @param reusable true if the entry is deemed * reusable, false otherwise. * @param validDuration The duration that the entry should remain free and reusable. * @param timeUnit The unit of time the duration is measured in. */ public abstract void freeEntry(BasicPoolEntry entry, boolean reusable, long validDuration, TimeUnit timeUnit) ; public void handleReference(final Reference ref) { } protected abstract void handleLostEntry(HttpRoute route); /** * Closes idle connections. * * @param idletime the time the connections should have been idle * in order to be closed now * @param tunit the unit for the idletime */ public void closeIdleConnections(final long idletime, final TimeUnit tunit) { // idletime can be 0 or negative, no problem there Args.notNull(tunit, "Time unit"); poolLock.lock(); try { idleConnHandler.closeIdleConnections(tunit.toMillis(idletime)); } finally { poolLock.unlock(); } } public void closeExpiredConnections() { poolLock.lock(); try { idleConnHandler.closeExpiredConnections(); } finally { poolLock.unlock(); } } /** * Deletes all entries for closed connections. */ public abstract void deleteClosedConnections(); /** * Shuts down this pool and all associated resources. * Overriding methods MUST call the implementation here! */ public void shutdown() { poolLock.lock(); try { if (isShutDown) { return; } // close all connections that are issued to an application final Iterator iter = leasedConnections.iterator(); while (iter.hasNext()) { final BasicPoolEntry entry = iter.next(); iter.remove(); closeConnection(entry.getConnection()); } idleConnHandler.removeAll(); isShutDown = true; } finally { poolLock.unlock(); } } /** * Closes a connection from this pool. * * @param conn the connection to close, or null */ protected void closeConnection(final OperatedClientConnection conn) { if (conn != null) { try { conn.close(); } catch (final IOException ex) { log.debug("I/O error closing connection", ex); } } } } // class AbstractConnPool ././@LongLink0100644 0000000 0000000 00000000174 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/BasicPooledConnAdapter.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/Basi0100644 0000000 0000000 00000005041 12301751664 032325 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn.tsccm; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.impl.conn.AbstractPoolEntry; import org.apache.http.impl.conn.AbstractPooledConnAdapter; /** * A connection wrapper and callback handler. * All connections given out by the manager are wrappers which * can be {@link #detach detach}ed to prevent further use on release. * * @since 4.0 * * @deprecated (4.2) do not use */ @Deprecated public class BasicPooledConnAdapter extends AbstractPooledConnAdapter { /** * Creates a new adapter. * * @param tsccm the connection manager * @param entry the pool entry for the connection being wrapped */ protected BasicPooledConnAdapter(final ThreadSafeClientConnManager tsccm, final AbstractPoolEntry entry) { super(tsccm, entry); markReusable(); } @Override protected ClientConnectionManager getManager() { // override needed only to make method visible in this package return super.getManager(); } @Override protected AbstractPoolEntry getPoolEntry() { // override needed only to make method visible in this package return super.getPoolEntry(); } @Override protected void detach() { // override needed only to make method visible in this package super.detach(); } } ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/BasicPoolEntry.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/Basi0100644 0000000 0000000 00000011133 12301751664 032324 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn.tsccm; import java.lang.ref.ReferenceQueue; import java.util.concurrent.TimeUnit; import org.apache.http.conn.ClientConnectionOperator; import org.apache.http.conn.OperatedClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.impl.conn.AbstractPoolEntry; import org.apache.http.util.Args; /** * Basic implementation of a connection pool entry. * * @since 4.0 * * @deprecated (4.2) use {@link org.apache.http.pool.PoolEntry} */ @Deprecated public class BasicPoolEntry extends AbstractPoolEntry { private final long created; private long updated; private final long validUntil; private long expiry; public BasicPoolEntry(final ClientConnectionOperator op, final HttpRoute route, final ReferenceQueue queue) { super(op, route); Args.notNull(route, "HTTP route"); this.created = System.currentTimeMillis(); this.validUntil = Long.MAX_VALUE; this.expiry = this.validUntil; } /** * Creates a new pool entry. * * @param op the connection operator * @param route the planned route for the connection */ public BasicPoolEntry(final ClientConnectionOperator op, final HttpRoute route) { this(op, route, -1, TimeUnit.MILLISECONDS); } /** * Creates a new pool entry with a specified maximum lifetime. * * @param op the connection operator * @param route the planned route for the connection * @param connTTL maximum lifetime of this entry, <=0 implies "infinity" * @param timeunit TimeUnit of connTTL * * @since 4.1 */ public BasicPoolEntry(final ClientConnectionOperator op, final HttpRoute route, final long connTTL, final TimeUnit timeunit) { super(op, route); Args.notNull(route, "HTTP route"); this.created = System.currentTimeMillis(); if (connTTL > 0) { this.validUntil = this.created + timeunit.toMillis(connTTL); } else { this.validUntil = Long.MAX_VALUE; } this.expiry = this.validUntil; } protected final OperatedClientConnection getConnection() { return super.connection; } protected final HttpRoute getPlannedRoute() { return super.route; } protected final BasicPoolEntryRef getWeakRef() { return null; } @Override protected void shutdownEntry() { super.shutdownEntry(); } /** * @since 4.1 */ public long getCreated() { return this.created; } /** * @since 4.1 */ public long getUpdated() { return this.updated; } /** * @since 4.1 */ public long getExpiry() { return this.expiry; } public long getValidUntil() { return this.validUntil; } /** * @since 4.1 */ public void updateExpiry(final long time, final TimeUnit timeunit) { this.updated = System.currentTimeMillis(); final long newExpiry; if (time > 0) { newExpiry = this.updated + timeunit.toMillis(time); } else { newExpiry = Long.MAX_VALUE; } this.expiry = Math.min(validUntil, newExpiry); } /** * @since 4.1 */ public boolean isExpired(final long now) { return now >= this.expiry; } } ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/BasicPoolEntryRef.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/Basi0100644 0000000 0000000 00000005012 12301751664 032323 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn.tsccm; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.util.Args; /** * A weak reference to a {@link BasicPoolEntry BasicPoolEntry}. * This reference explicitly keeps the planned route, so the connection * can be reclaimed if it is lost to garbage collection. * * @since 4.0 * * @deprecated (4.2) do not use */ @Deprecated public class BasicPoolEntryRef extends WeakReference { /** The planned route of the entry. */ private final HttpRoute route; // HttpRoute is @Immutable /** * Creates a new reference to a pool entry. * * @param entry the pool entry, must not be null * @param queue the reference queue, or null */ public BasicPoolEntryRef(final BasicPoolEntry entry, final ReferenceQueue queue) { super(entry, queue); Args.notNull(entry, "Pool entry"); route = entry.getPlannedRoute(); } /** * Obtain the planned route for the referenced entry. * The planned route is still available, even if the entry is gone. * * @return the planned route */ public final HttpRoute getRoute() { return this.route; } } // class BasicPoolEntryRef ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/ConnPoolByRoute.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/Conn0100644 0000000 0000000 00000066513 12301751664 032357 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn.tsccm; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import java.util.Queue; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.conn.ClientConnectionOperator; import org.apache.http.conn.ConnectionPoolTimeoutException; import org.apache.http.conn.OperatedClientConnection; import org.apache.http.conn.params.ConnManagerParams; import org.apache.http.conn.params.ConnPerRoute; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.params.HttpParams; import org.apache.http.util.Args; import org.apache.http.util.Asserts; /** * A connection pool that maintains connections by route. * This class is derived from MultiThreadedHttpConnectionManager * in HttpClient 3.x, see there for original authors. It implements the same * algorithm for connection re-use and connection-per-host enforcement: *
    *
  • connections are re-used only for the exact same route
  • *
  • connection limits are enforced per route rather than per host
  • *
* Note that access to the pool data structures is synchronized via the * {@link AbstractConnPool#poolLock poolLock} in the base class, * not via synchronized methods. * * @since 4.0 * * @deprecated (4.2) use {@link org.apache.http.pool.AbstractConnPool} */ @Deprecated public class ConnPoolByRoute extends AbstractConnPool { private final Log log = LogFactory.getLog(getClass()); private final Lock poolLock; /** Connection operator for this pool */ protected final ClientConnectionOperator operator; /** Connections per route lookup */ protected final ConnPerRoute connPerRoute; /** References to issued connections */ protected final Set leasedConnections; /** The list of free connections */ protected final Queue freeConnections; /** The list of WaitingThreads waiting for a connection */ protected final Queue waitingThreads; /** Map of route-specific pools */ protected final Map routeToPool; private final long connTTL; private final TimeUnit connTTLTimeUnit; protected volatile boolean shutdown; protected volatile int maxTotalConnections; protected volatile int numConnections; /** * Creates a new connection pool, managed by route. * * @since 4.1 */ public ConnPoolByRoute( final ClientConnectionOperator operator, final ConnPerRoute connPerRoute, final int maxTotalConnections) { this(operator, connPerRoute, maxTotalConnections, -1, TimeUnit.MILLISECONDS); } /** * @since 4.1 */ public ConnPoolByRoute( final ClientConnectionOperator operator, final ConnPerRoute connPerRoute, final int maxTotalConnections, final long connTTL, final TimeUnit connTTLTimeUnit) { super(); Args.notNull(operator, "Connection operator"); Args.notNull(connPerRoute, "Connections per route"); this.poolLock = super.poolLock; this.leasedConnections = super.leasedConnections; this.operator = operator; this.connPerRoute = connPerRoute; this.maxTotalConnections = maxTotalConnections; this.freeConnections = createFreeConnQueue(); this.waitingThreads = createWaitingThreadQueue(); this.routeToPool = createRouteToPoolMap(); this.connTTL = connTTL; this.connTTLTimeUnit = connTTLTimeUnit; } protected Lock getLock() { return this.poolLock; } /** * Creates a new connection pool, managed by route. * * @deprecated (4.1) use {@link ConnPoolByRoute#ConnPoolByRoute(ClientConnectionOperator, ConnPerRoute, int)} */ @Deprecated public ConnPoolByRoute(final ClientConnectionOperator operator, final HttpParams params) { this(operator, ConnManagerParams.getMaxConnectionsPerRoute(params), ConnManagerParams.getMaxTotalConnections(params)); } /** * Creates the queue for {@link #freeConnections}. * Called once by the constructor. * * @return a queue */ protected Queue createFreeConnQueue() { return new LinkedList(); } /** * Creates the queue for {@link #waitingThreads}. * Called once by the constructor. * * @return a queue */ protected Queue createWaitingThreadQueue() { return new LinkedList(); } /** * Creates the map for {@link #routeToPool}. * Called once by the constructor. * * @return a map */ protected Map createRouteToPoolMap() { return new HashMap(); } /** * Creates a new route-specific pool. * Called by {@link #getRoutePool} when necessary. * * @param route the route * * @return the new pool */ protected RouteSpecificPool newRouteSpecificPool(final HttpRoute route) { return new RouteSpecificPool(route, this.connPerRoute); } /** * Creates a new waiting thread. * Called by {@link #getRoutePool} when necessary. * * @param cond the condition to wait for * @param rospl the route specific pool, or null * * @return a waiting thread representation */ protected WaitingThread newWaitingThread(final Condition cond, final RouteSpecificPool rospl) { return new WaitingThread(cond, rospl); } private void closeConnection(final BasicPoolEntry entry) { final OperatedClientConnection conn = entry.getConnection(); if (conn != null) { try { conn.close(); } catch (final IOException ex) { log.debug("I/O error closing connection", ex); } } } /** * Get a route-specific pool of available connections. * * @param route the route * @param create whether to create the pool if it doesn't exist * * @return the pool for the argument route, * never null if create is true */ protected RouteSpecificPool getRoutePool(final HttpRoute route, final boolean create) { RouteSpecificPool rospl = null; poolLock.lock(); try { rospl = routeToPool.get(route); if ((rospl == null) && create) { // no pool for this route yet (or anymore) rospl = newRouteSpecificPool(route); routeToPool.put(route, rospl); } } finally { poolLock.unlock(); } return rospl; } public int getConnectionsInPool(final HttpRoute route) { poolLock.lock(); try { // don't allow a pool to be created here! final RouteSpecificPool rospl = getRoutePool(route, false); return (rospl != null) ? rospl.getEntryCount() : 0; } finally { poolLock.unlock(); } } public int getConnectionsInPool() { poolLock.lock(); try { return numConnections; } finally { poolLock.unlock(); } } @Override public PoolEntryRequest requestPoolEntry( final HttpRoute route, final Object state) { final WaitingThreadAborter aborter = new WaitingThreadAborter(); return new PoolEntryRequest() { public void abortRequest() { poolLock.lock(); try { aborter.abort(); } finally { poolLock.unlock(); } } public BasicPoolEntry getPoolEntry( final long timeout, final TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException { return getEntryBlocking(route, state, timeout, tunit, aborter); } }; } /** * Obtains a pool entry with a connection within the given timeout. * If a {@link WaitingThread} is used to block, {@link WaitingThreadAborter#setWaitingThread(WaitingThread)} * must be called before blocking, to allow the thread to be interrupted. * * @param route the route for which to get the connection * @param timeout the timeout, 0 or negative for no timeout * @param tunit the unit for the timeout, * may be null only if there is no timeout * @param aborter an object which can abort a {@link WaitingThread}. * * @return pool entry holding a connection for the route * * @throws ConnectionPoolTimeoutException * if the timeout expired * @throws InterruptedException * if the calling thread was interrupted */ protected BasicPoolEntry getEntryBlocking( final HttpRoute route, final Object state, final long timeout, final TimeUnit tunit, final WaitingThreadAborter aborter) throws ConnectionPoolTimeoutException, InterruptedException { Date deadline = null; if (timeout > 0) { deadline = new Date (System.currentTimeMillis() + tunit.toMillis(timeout)); } BasicPoolEntry entry = null; poolLock.lock(); try { RouteSpecificPool rospl = getRoutePool(route, true); WaitingThread waitingThread = null; while (entry == null) { Asserts.check(!shutdown, "Connection pool shut down"); if (log.isDebugEnabled()) { log.debug("[" + route + "] total kept alive: " + freeConnections.size() + ", total issued: " + leasedConnections.size() + ", total allocated: " + numConnections + " out of " + maxTotalConnections); } // the cases to check for: // - have a free connection for that route // - allowed to create a free connection for that route // - can delete and replace a free connection for another route // - need to wait for one of the things above to come true entry = getFreeEntry(rospl, state); if (entry != null) { break; } final boolean hasCapacity = rospl.getCapacity() > 0; if (log.isDebugEnabled()) { log.debug("Available capacity: " + rospl.getCapacity() + " out of " + rospl.getMaxEntries() + " [" + route + "][" + state + "]"); } if (hasCapacity && numConnections < maxTotalConnections) { entry = createEntry(rospl, operator); } else if (hasCapacity && !freeConnections.isEmpty()) { deleteLeastUsedEntry(); // if least used entry's route was the same as rospl, // rospl is now out of date : we preemptively refresh rospl = getRoutePool(route, true); entry = createEntry(rospl, operator); } else { if (log.isDebugEnabled()) { log.debug("Need to wait for connection" + " [" + route + "][" + state + "]"); } if (waitingThread == null) { waitingThread = newWaitingThread(poolLock.newCondition(), rospl); aborter.setWaitingThread(waitingThread); } boolean success = false; try { rospl.queueThread(waitingThread); waitingThreads.add(waitingThread); success = waitingThread.await(deadline); } finally { // In case of 'success', we were woken up by the // connection pool and should now have a connection // waiting for us, or else we're shutting down. // Just continue in the loop, both cases are checked. rospl.removeThread(waitingThread); waitingThreads.remove(waitingThread); } // check for spurious wakeup vs. timeout if (!success && (deadline != null) && (deadline.getTime() <= System.currentTimeMillis())) { throw new ConnectionPoolTimeoutException ("Timeout waiting for connection from pool"); } } } // while no entry } finally { poolLock.unlock(); } return entry; } @Override public void freeEntry(final BasicPoolEntry entry, final boolean reusable, final long validDuration, final TimeUnit timeUnit) { final HttpRoute route = entry.getPlannedRoute(); if (log.isDebugEnabled()) { log.debug("Releasing connection" + " [" + route + "][" + entry.getState() + "]"); } poolLock.lock(); try { if (shutdown) { // the pool is shut down, release the // connection's resources and get out of here closeConnection(entry); return; } // no longer issued, we keep a hard reference now leasedConnections.remove(entry); final RouteSpecificPool rospl = getRoutePool(route, true); if (reusable && rospl.getCapacity() >= 0) { if (log.isDebugEnabled()) { final String s; if (validDuration > 0) { s = "for " + validDuration + " " + timeUnit; } else { s = "indefinitely"; } log.debug("Pooling connection" + " [" + route + "][" + entry.getState() + "]; keep alive " + s); } rospl.freeEntry(entry); entry.updateExpiry(validDuration, timeUnit); freeConnections.add(entry); } else { closeConnection(entry); rospl.dropEntry(); numConnections--; } notifyWaitingThread(rospl); } finally { poolLock.unlock(); } } /** * If available, get a free pool entry for a route. * * @param rospl the route-specific pool from which to get an entry * * @return an available pool entry for the given route, or * null if none is available */ protected BasicPoolEntry getFreeEntry(final RouteSpecificPool rospl, final Object state) { BasicPoolEntry entry = null; poolLock.lock(); try { boolean done = false; while(!done) { entry = rospl.allocEntry(state); if (entry != null) { if (log.isDebugEnabled()) { log.debug("Getting free connection" + " [" + rospl.getRoute() + "][" + state + "]"); } freeConnections.remove(entry); if (entry.isExpired(System.currentTimeMillis())) { // If the free entry isn't valid anymore, get rid of it // and loop to find another one that might be valid. if (log.isDebugEnabled()) { log.debug("Closing expired free connection" + " [" + rospl.getRoute() + "][" + state + "]"); } closeConnection(entry); // We use dropEntry instead of deleteEntry because the entry // is no longer "free" (we just allocated it), and deleteEntry // can only be used to delete free entries. rospl.dropEntry(); numConnections--; } else { leasedConnections.add(entry); done = true; } } else { done = true; if (log.isDebugEnabled()) { log.debug("No free connections" + " [" + rospl.getRoute() + "][" + state + "]"); } } } } finally { poolLock.unlock(); } return entry; } /** * Creates a new pool entry. * This method assumes that the new connection will be handed * out immediately. * * @param rospl the route-specific pool for which to create the entry * @param op the operator for creating a connection * * @return the new pool entry for a new connection */ protected BasicPoolEntry createEntry(final RouteSpecificPool rospl, final ClientConnectionOperator op) { if (log.isDebugEnabled()) { log.debug("Creating new connection [" + rospl.getRoute() + "]"); } // the entry will create the connection when needed final BasicPoolEntry entry = new BasicPoolEntry(op, rospl.getRoute(), connTTL, connTTLTimeUnit); poolLock.lock(); try { rospl.createdEntry(entry); numConnections++; leasedConnections.add(entry); } finally { poolLock.unlock(); } return entry; } /** * Deletes a given pool entry. * This closes the pooled connection and removes all references, * so that it can be GCed. * *

Note: Does not remove the entry from the freeConnections list. * It is assumed that the caller has already handled this step.

* * * @param entry the pool entry for the connection to delete */ protected void deleteEntry(final BasicPoolEntry entry) { final HttpRoute route = entry.getPlannedRoute(); if (log.isDebugEnabled()) { log.debug("Deleting connection" + " [" + route + "][" + entry.getState() + "]"); } poolLock.lock(); try { closeConnection(entry); final RouteSpecificPool rospl = getRoutePool(route, true); rospl.deleteEntry(entry); numConnections--; if (rospl.isUnused()) { routeToPool.remove(route); } } finally { poolLock.unlock(); } } /** * Delete an old, free pool entry to make room for a new one. * Used to replace pool entries with ones for a different route. */ protected void deleteLeastUsedEntry() { poolLock.lock(); try { final BasicPoolEntry entry = freeConnections.remove(); if (entry != null) { deleteEntry(entry); } else if (log.isDebugEnabled()) { log.debug("No free connection to delete"); } } finally { poolLock.unlock(); } } @Override protected void handleLostEntry(final HttpRoute route) { poolLock.lock(); try { final RouteSpecificPool rospl = getRoutePool(route, true); rospl.dropEntry(); if (rospl.isUnused()) { routeToPool.remove(route); } numConnections--; notifyWaitingThread(rospl); } finally { poolLock.unlock(); } } /** * Notifies a waiting thread that a connection is available. * This will wake a thread waiting in the specific route pool, * if there is one. * Otherwise, a thread in the connection pool will be notified. * * @param rospl the pool in which to notify, or null */ protected void notifyWaitingThread(final RouteSpecificPool rospl) { //@@@ while this strategy provides for best connection re-use, //@@@ is it fair? only do this if the connection is open? // Find the thread we are going to notify. We want to ensure that // each waiting thread is only interrupted once, so we will remove // it from all wait queues before interrupting. WaitingThread waitingThread = null; poolLock.lock(); try { if ((rospl != null) && rospl.hasThread()) { if (log.isDebugEnabled()) { log.debug("Notifying thread waiting on pool" + " [" + rospl.getRoute() + "]"); } waitingThread = rospl.nextThread(); } else if (!waitingThreads.isEmpty()) { if (log.isDebugEnabled()) { log.debug("Notifying thread waiting on any pool"); } waitingThread = waitingThreads.remove(); } else if (log.isDebugEnabled()) { log.debug("Notifying no-one, there are no waiting threads"); } if (waitingThread != null) { waitingThread.wakeup(); } } finally { poolLock.unlock(); } } @Override public void deleteClosedConnections() { poolLock.lock(); try { final Iterator iter = freeConnections.iterator(); while (iter.hasNext()) { final BasicPoolEntry entry = iter.next(); if (!entry.getConnection().isOpen()) { iter.remove(); deleteEntry(entry); } } } finally { poolLock.unlock(); } } /** * Closes idle connections. * * @param idletime the time the connections should have been idle * in order to be closed now * @param tunit the unit for the idletime */ @Override public void closeIdleConnections(final long idletime, final TimeUnit tunit) { Args.notNull(tunit, "Time unit"); final long t = idletime > 0 ? idletime : 0; if (log.isDebugEnabled()) { log.debug("Closing connections idle longer than " + t + " " + tunit); } // the latest time for which connections will be closed final long deadline = System.currentTimeMillis() - tunit.toMillis(t); poolLock.lock(); try { final Iterator iter = freeConnections.iterator(); while (iter.hasNext()) { final BasicPoolEntry entry = iter.next(); if (entry.getUpdated() <= deadline) { if (log.isDebugEnabled()) { log.debug("Closing connection last used @ " + new Date(entry.getUpdated())); } iter.remove(); deleteEntry(entry); } } } finally { poolLock.unlock(); } } @Override public void closeExpiredConnections() { log.debug("Closing expired connections"); final long now = System.currentTimeMillis(); poolLock.lock(); try { final Iterator iter = freeConnections.iterator(); while (iter.hasNext()) { final BasicPoolEntry entry = iter.next(); if (entry.isExpired(now)) { if (log.isDebugEnabled()) { log.debug("Closing connection expired @ " + new Date(entry.getExpiry())); } iter.remove(); deleteEntry(entry); } } } finally { poolLock.unlock(); } } @Override public void shutdown() { poolLock.lock(); try { if (shutdown) { return; } shutdown = true; // close all connections that are issued to an application final Iterator iter1 = leasedConnections.iterator(); while (iter1.hasNext()) { final BasicPoolEntry entry = iter1.next(); iter1.remove(); closeConnection(entry); } // close all free connections final Iterator iter2 = freeConnections.iterator(); while (iter2.hasNext()) { final BasicPoolEntry entry = iter2.next(); iter2.remove(); if (log.isDebugEnabled()) { log.debug("Closing connection" + " [" + entry.getPlannedRoute() + "][" + entry.getState() + "]"); } closeConnection(entry); } // wake up all waiting threads final Iterator iwth = waitingThreads.iterator(); while (iwth.hasNext()) { final WaitingThread waiter = iwth.next(); iwth.remove(); waiter.wakeup(); } routeToPool.clear(); } finally { poolLock.unlock(); } } /** * since 4.1 */ public void setMaxTotalConnections(final int max) { poolLock.lock(); try { maxTotalConnections = max; } finally { poolLock.unlock(); } } /** * since 4.1 */ public int getMaxTotalConnections() { return maxTotalConnections; } } ././@LongLink0100644 0000000 0000000 00000000162 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/package-info.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/pack0100644 0000000 0000000 00000002371 12301751664 032370 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Deprecated. * * @deprecated (4.3) */ package org.apache.http.impl.conn.tsccm; ././@LongLink0100644 0000000 0000000 00000000166 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/PoolEntryRequest.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/Pool0100644 0000000 0000000 00000004676 12301751664 032375 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn.tsccm; import java.util.concurrent.TimeUnit; import org.apache.http.conn.ConnectionPoolTimeoutException; /** * Encapsulates a request for a {@link BasicPoolEntry}. * * @since 4.0 * * @deprecated (4.2) use {@link java.util.concurrent.Future} */ @Deprecated public interface PoolEntryRequest { /** * Obtains a pool entry with a connection within the given timeout. * If {@link #abortRequest()} is called before this completes * an {@link InterruptedException} is thrown. * * @param timeout the timeout, 0 or negative for no timeout * @param tunit the unit for the timeout, * may be null only if there is no timeout * * @return pool entry holding a connection for the route * * @throws ConnectionPoolTimeoutException * if the timeout expired * @throws InterruptedException * if the calling thread was interrupted or the request was aborted */ BasicPoolEntry getPoolEntry( long timeout, TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException; /** * Aborts the active or next call to * {@link #getPoolEntry(long, TimeUnit)}. */ void abortRequest(); } ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/RouteSpecificPool.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/Rout0100644 0000000 0000000 00000022763 12301751664 032412 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn.tsccm; import java.io.IOException; import java.util.LinkedList; import java.util.ListIterator; import java.util.Queue; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.conn.OperatedClientConnection; import org.apache.http.conn.params.ConnPerRoute; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.util.Args; import org.apache.http.util.Asserts; import org.apache.http.util.LangUtils; /** * A connection sub-pool for a specific route, used by {@link ConnPoolByRoute}. * The methods in this class are unsynchronized. It is expected that the * containing pool takes care of synchronization. * * @since 4.0 * * @deprecated (4.2) use {@link org.apache.http.pool.AbstractConnPool} */ @Deprecated public class RouteSpecificPool { private final Log log = LogFactory.getLog(getClass()); /** The route this pool is for. */ protected final HttpRoute route; //Immutable protected final int maxEntries; /** Connections per route */ protected final ConnPerRoute connPerRoute; /** * The list of free entries. * This list is managed LIFO, to increase idle times and * allow for closing connections that are not really needed. */ protected final LinkedList freeEntries; /** The list of threads waiting for this pool. */ protected final Queue waitingThreads; /** The number of created entries. */ protected int numEntries; /** * @deprecated (4.1) use {@link RouteSpecificPool#RouteSpecificPool(HttpRoute, ConnPerRoute)} */ @Deprecated public RouteSpecificPool(final HttpRoute route, final int maxEntries) { this.route = route; this.maxEntries = maxEntries; this.connPerRoute = new ConnPerRoute() { public int getMaxForRoute(final HttpRoute route) { return RouteSpecificPool.this.maxEntries; } }; this.freeEntries = new LinkedList(); this.waitingThreads = new LinkedList(); this.numEntries = 0; } /** * Creates a new route-specific pool. * * @param route the route for which to pool * @param connPerRoute the connections per route configuration */ public RouteSpecificPool(final HttpRoute route, final ConnPerRoute connPerRoute) { this.route = route; this.connPerRoute = connPerRoute; this.maxEntries = connPerRoute.getMaxForRoute(route); this.freeEntries = new LinkedList(); this.waitingThreads = new LinkedList(); this.numEntries = 0; } /** * Obtains the route for which this pool is specific. * * @return the route */ public final HttpRoute getRoute() { return route; } /** * Obtains the maximum number of entries allowed for this pool. * * @return the max entry number */ public final int getMaxEntries() { return maxEntries; } /** * Indicates whether this pool is unused. * A pool is unused if there is neither an entry nor a waiting thread. * All entries count, not only the free but also the allocated ones. * * @return true if this pool is unused, * false otherwise */ public boolean isUnused() { return (numEntries < 1) && waitingThreads.isEmpty(); } /** * Return remaining capacity of this pool * * @return capacity */ public int getCapacity() { return connPerRoute.getMaxForRoute(route) - numEntries; } /** * Obtains the number of entries. * This includes not only the free entries, but also those that * have been created and are currently issued to an application. * * @return the number of entries for the route of this pool */ public final int getEntryCount() { return numEntries; } /** * Obtains a free entry from this pool, if one is available. * * @return an available pool entry, or null if there is none */ public BasicPoolEntry allocEntry(final Object state) { if (!freeEntries.isEmpty()) { final ListIterator it = freeEntries.listIterator(freeEntries.size()); while (it.hasPrevious()) { final BasicPoolEntry entry = it.previous(); if (entry.getState() == null || LangUtils.equals(state, entry.getState())) { it.remove(); return entry; } } } if (getCapacity() == 0 && !freeEntries.isEmpty()) { final BasicPoolEntry entry = freeEntries.remove(); entry.shutdownEntry(); final OperatedClientConnection conn = entry.getConnection(); try { conn.close(); } catch (final IOException ex) { log.debug("I/O error closing connection", ex); } return entry; } return null; } /** * Returns an allocated entry to this pool. * * @param entry the entry obtained from {@link #allocEntry allocEntry} * or presented to {@link #createdEntry createdEntry} */ public void freeEntry(final BasicPoolEntry entry) { if (numEntries < 1) { throw new IllegalStateException ("No entry created for this pool. " + route); } if (numEntries <= freeEntries.size()) { throw new IllegalStateException ("No entry allocated from this pool. " + route); } freeEntries.add(entry); } /** * Indicates creation of an entry for this pool. * The entry will not be added to the list of free entries, * it is only recognized as belonging to this pool now. It can then * be passed to {@link #freeEntry freeEntry}. * * @param entry the entry that was created for this pool */ public void createdEntry(final BasicPoolEntry entry) { Args.check(route.equals(entry.getPlannedRoute()), "Entry not planned for this pool"); numEntries++; } /** * Deletes an entry from this pool. * Only entries that are currently free in this pool can be deleted. * Allocated entries can not be deleted. * * @param entry the entry to delete from this pool * * @return true if the entry was found and deleted, or * false if the entry was not found */ public boolean deleteEntry(final BasicPoolEntry entry) { final boolean found = freeEntries.remove(entry); if (found) { numEntries--; } return found; } /** * Forgets about an entry from this pool. * This method is used to indicate that an entry * {@link #allocEntry allocated} * from this pool has been lost and will not be returned. */ public void dropEntry() { Asserts.check(numEntries > 0, "There is no entry that could be dropped"); numEntries--; } /** * Adds a waiting thread. * This pool makes no attempt to match waiting threads with pool entries. * It is the caller's responsibility to check that there is no entry * before adding a waiting thread. * * @param wt the waiting thread */ public void queueThread(final WaitingThread wt) { Args.notNull(wt, "Waiting thread"); this.waitingThreads.add(wt); } /** * Checks whether there is a waiting thread in this pool. * * @return true if there is a waiting thread, * false otherwise */ public boolean hasThread() { return !this.waitingThreads.isEmpty(); } /** * Returns the next thread in the queue. * * @return a waiting thread, or null if there is none */ public WaitingThread nextThread() { return this.waitingThreads.peek(); } /** * Removes a waiting thread, if it is queued. * * @param wt the waiting thread */ public void removeThread(final WaitingThread wt) { if (wt == null) { return; } this.waitingThreads.remove(wt); } } // class RouteSpecificPool ././@LongLink0100644 0000000 0000000 00000000201 12302131605 011615 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/Thre0100644 0000000 0000000 00000032201 12301751664 032347 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn.tsccm; import java.io.IOException; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.annotation.ThreadSafe; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.ClientConnectionOperator; import org.apache.http.conn.ClientConnectionRequest; import org.apache.http.conn.ConnectionPoolTimeoutException; import org.apache.http.conn.ManagedClientConnection; import org.apache.http.conn.params.ConnPerRouteBean; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.impl.conn.DefaultClientConnectionOperator; import org.apache.http.impl.conn.SchemeRegistryFactory; import org.apache.http.params.HttpParams; import org.apache.http.util.Args; import org.apache.http.util.Asserts; /** * Manages a pool of {@link org.apache.http.conn.OperatedClientConnection } * and is able to service connection requests from multiple execution threads. * Connections are pooled on a per route basis. A request for a route which * already the manager has persistent connections for available in the pool * will be services by leasing a connection from the pool rather than * creating a brand new connection. *

* ThreadSafeClientConnManager maintains a maximum limit of connection on * a per route basis and in total. Per default this implementation will * create no more than than 2 concurrent connections per given route * and no more 20 connections in total. For many real-world applications * these limits may prove too constraining, especially if they use HTTP * as a transport protocol for their services. Connection limits, however, * can be adjusted using HTTP parameters. * * @since 4.0 * * @deprecated (4.2) use {@link org.apache.http.impl.conn.PoolingHttpClientConnectionManager} */ @ThreadSafe @Deprecated public class ThreadSafeClientConnManager implements ClientConnectionManager { private final Log log; /** The schemes supported by this connection manager. */ protected final SchemeRegistry schemeRegistry; // @ThreadSafe protected final AbstractConnPool connectionPool; /** The pool of connections being managed. */ protected final ConnPoolByRoute pool; /** The operator for opening and updating connections. */ protected final ClientConnectionOperator connOperator; // DefaultClientConnectionOperator is @ThreadSafe protected final ConnPerRouteBean connPerRoute; /** * Creates a new thread safe connection manager. * * @param schreg the scheme registry. */ public ThreadSafeClientConnManager(final SchemeRegistry schreg) { this(schreg, -1, TimeUnit.MILLISECONDS); } /** * @since 4.1 */ public ThreadSafeClientConnManager() { this(SchemeRegistryFactory.createDefault()); } /** * Creates a new thread safe connection manager. * * @param schreg the scheme registry. * @param connTTL max connection lifetime, <=0 implies "infinity" * @param connTTLTimeUnit TimeUnit of connTTL * * @since 4.1 */ public ThreadSafeClientConnManager(final SchemeRegistry schreg, final long connTTL, final TimeUnit connTTLTimeUnit) { this(schreg, connTTL, connTTLTimeUnit, new ConnPerRouteBean()); } /** * Creates a new thread safe connection manager. * * @param schreg the scheme registry. * @param connTTL max connection lifetime, <=0 implies "infinity" * @param connTTLTimeUnit TimeUnit of connTTL * @param connPerRoute mapping of maximum connections per route, * provided as a dependency so it can be managed externally, e.g. * for dynamic connection pool size management. * * @since 4.2 */ public ThreadSafeClientConnManager(final SchemeRegistry schreg, final long connTTL, final TimeUnit connTTLTimeUnit, final ConnPerRouteBean connPerRoute) { super(); Args.notNull(schreg, "Scheme registry"); this.log = LogFactory.getLog(getClass()); this.schemeRegistry = schreg; this.connPerRoute = connPerRoute; this.connOperator = createConnectionOperator(schreg); this.pool = createConnectionPool(connTTL, connTTLTimeUnit) ; this.connectionPool = this.pool; } /** * Creates a new thread safe connection manager. * * @param params the parameters for this manager. * @param schreg the scheme registry. * * @deprecated (4.1) use {@link ThreadSafeClientConnManager#ThreadSafeClientConnManager(SchemeRegistry)} */ @Deprecated public ThreadSafeClientConnManager(final HttpParams params, final SchemeRegistry schreg) { Args.notNull(schreg, "Scheme registry"); this.log = LogFactory.getLog(getClass()); this.schemeRegistry = schreg; this.connPerRoute = new ConnPerRouteBean(); this.connOperator = createConnectionOperator(schreg); this.pool = (ConnPoolByRoute) createConnectionPool(params) ; this.connectionPool = this.pool; } @Override protected void finalize() throws Throwable { try { shutdown(); } finally { super.finalize(); } } /** * Hook for creating the connection pool. * * @return the connection pool to use * * @deprecated (4.1) use #createConnectionPool(long, TimeUnit)) */ @Deprecated protected AbstractConnPool createConnectionPool(final HttpParams params) { return new ConnPoolByRoute(connOperator, params); } /** * Hook for creating the connection pool. * * @return the connection pool to use * * @since 4.1 */ protected ConnPoolByRoute createConnectionPool(final long connTTL, final TimeUnit connTTLTimeUnit) { return new ConnPoolByRoute(connOperator, connPerRoute, 20, connTTL, connTTLTimeUnit); } /** * Hook for creating the connection operator. * It is called by the constructor. * Derived classes can override this method to change the * instantiation of the operator. * The default implementation here instantiates * {@link DefaultClientConnectionOperator DefaultClientConnectionOperator}. * * @param schreg the scheme registry. * * @return the connection operator to use */ protected ClientConnectionOperator createConnectionOperator(final SchemeRegistry schreg) { return new DefaultClientConnectionOperator(schreg);// @ThreadSafe } public SchemeRegistry getSchemeRegistry() { return this.schemeRegistry; } public ClientConnectionRequest requestConnection( final HttpRoute route, final Object state) { final PoolEntryRequest poolRequest = pool.requestPoolEntry( route, state); return new ClientConnectionRequest() { public void abortRequest() { poolRequest.abortRequest(); } public ManagedClientConnection getConnection( final long timeout, final TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException { Args.notNull(route, "Route"); if (log.isDebugEnabled()) { log.debug("Get connection: " + route + ", timeout = " + timeout); } final BasicPoolEntry entry = poolRequest.getPoolEntry(timeout, tunit); return new BasicPooledConnAdapter(ThreadSafeClientConnManager.this, entry); } }; } public void releaseConnection(final ManagedClientConnection conn, final long validDuration, final TimeUnit timeUnit) { Args.check(conn instanceof BasicPooledConnAdapter, "Connection class mismatch, " + "connection not obtained from this manager"); final BasicPooledConnAdapter hca = (BasicPooledConnAdapter) conn; if (hca.getPoolEntry() != null) { Asserts.check(hca.getManager() == this, "Connection not obtained from this manager"); } synchronized (hca) { final BasicPoolEntry entry = (BasicPoolEntry) hca.getPoolEntry(); if (entry == null) { return; } try { // make sure that the response has been read completely if (hca.isOpen() && !hca.isMarkedReusable()) { // In MTHCM, there would be a call to // SimpleHttpConnectionManager.finishLastResponse(conn); // Consuming the response is handled outside in 4.0. // make sure this connection will not be re-used // Shut down rather than close, we might have gotten here // because of a shutdown trigger. // Shutdown of the adapter also clears the tracked route. hca.shutdown(); } } catch (final IOException iox) { if (log.isDebugEnabled()) { log.debug("Exception shutting down released connection.", iox); } } finally { final boolean reusable = hca.isMarkedReusable(); if (log.isDebugEnabled()) { if (reusable) { log.debug("Released connection is reusable."); } else { log.debug("Released connection is not reusable."); } } hca.detach(); pool.freeEntry(entry, reusable, validDuration, timeUnit); } } } public void shutdown() { log.debug("Shutting down"); pool.shutdown(); } /** * Gets the total number of pooled connections for the given route. * This is the total number of connections that have been created and * are still in use by this connection manager for the route. * This value will not exceed the maximum number of connections per host. * * @param route the route in question * * @return the total number of pooled connections for that route */ public int getConnectionsInPool(final HttpRoute route) { return pool.getConnectionsInPool(route); } /** * Gets the total number of pooled connections. This is the total number of * connections that have been created and are still in use by this connection * manager. This value will not exceed the maximum number of connections * in total. * * @return the total number of pooled connections */ public int getConnectionsInPool() { return pool.getConnectionsInPool(); } public void closeIdleConnections(final long idleTimeout, final TimeUnit tunit) { if (log.isDebugEnabled()) { log.debug("Closing connections idle longer than " + idleTimeout + " " + tunit); } pool.closeIdleConnections(idleTimeout, tunit); } public void closeExpiredConnections() { log.debug("Closing expired connections"); pool.closeExpiredConnections(); } /** * since 4.1 */ public int getMaxTotal() { return pool.getMaxTotalConnections(); } /** * since 4.1 */ public void setMaxTotal(final int max) { pool.setMaxTotalConnections(max); } /** * @since 4.1 */ public int getDefaultMaxPerRoute() { return connPerRoute.getDefaultMaxPerRoute(); } /** * @since 4.1 */ public void setDefaultMaxPerRoute(final int max) { connPerRoute.setDefaultMaxPerRoute(max); } /** * @since 4.1 */ public int getMaxForRoute(final HttpRoute route) { return connPerRoute.getMaxForRoute(route); } /** * @since 4.1 */ public void setMaxForRoute(final HttpRoute route, final int max) { connPerRoute.setMaxForRoute(route, max); } } ././@LongLink0100644 0000000 0000000 00000000163 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/WaitingThread.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/Wait0100644 0000000 0000000 00000013611 12301751664 032355 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn.tsccm; import java.util.Date; import java.util.concurrent.locks.Condition; import org.apache.http.util.Args; /** * Represents a thread waiting for a connection. * This class implements throwaway objects. It is instantiated whenever * a thread needs to wait. Instances are not re-used, except if the * waiting thread experiences a spurious wakeup and continues to wait. *
* All methods assume external synchronization on the condition * passed to the constructor. * Instances of this class do not synchronize access! * * * @since 4.0 * * @deprecated (4.2) do not use */ @Deprecated public class WaitingThread { /** The condition on which the thread is waiting. */ private final Condition cond; /** The route specific pool on which the thread is waiting. */ //@@@ replace with generic pool interface private final RouteSpecificPool pool; /** The thread that is waiting for an entry. */ private Thread waiter; /** True if this was interrupted. */ private boolean aborted; /** * Creates a new entry for a waiting thread. * * @param cond the condition for which to wait * @param pool the pool on which the thread will be waiting, * or null */ public WaitingThread(final Condition cond, final RouteSpecificPool pool) { Args.notNull(cond, "Condition"); this.cond = cond; this.pool = pool; } /** * Obtains the condition. * * @return the condition on which to wait, never null */ public final Condition getCondition() { // not synchronized return this.cond; } /** * Obtains the pool, if there is one. * * @return the pool on which a thread is or was waiting, * or null */ public final RouteSpecificPool getPool() { // not synchronized return this.pool; } /** * Obtains the thread, if there is one. * * @return the thread which is waiting, or null */ public final Thread getThread() { // not synchronized return this.waiter; } /** * Blocks the calling thread. * This method returns when the thread is notified or interrupted, * if a timeout occurrs, or if there is a spurious wakeup. *
* This method assumes external synchronization. * * @param deadline when to time out, or null for no timeout * * @return true if the condition was satisfied, * false in case of a timeout. * Typically, a call to {@link #wakeup} is used to indicate * that the condition was satisfied. Since the condition is * accessible outside, this cannot be guaranteed though. * * @throws InterruptedException if the waiting thread was interrupted * * @see #wakeup */ public boolean await(final Date deadline) throws InterruptedException { // This is only a sanity check. We cannot synchronize here, // the lock would not be released on calling cond.await() below. if (this.waiter != null) { throw new IllegalStateException ("A thread is already waiting on this object." + "\ncaller: " + Thread.currentThread() + "\nwaiter: " + this.waiter); } if (aborted) { throw new InterruptedException("Operation interrupted"); } this.waiter = Thread.currentThread(); boolean success = false; try { if (deadline != null) { success = this.cond.awaitUntil(deadline); } else { this.cond.await(); success = true; } if (aborted) { throw new InterruptedException("Operation interrupted"); } } finally { this.waiter = null; } return success; } // await /** * Wakes up the waiting thread. *
* This method assumes external synchronization. */ public void wakeup() { // If external synchronization and pooling works properly, // this cannot happen. Just a sanity check. if (this.waiter == null) { throw new IllegalStateException ("Nobody waiting on this object."); } // One condition might be shared by several WaitingThread instances. // It probably isn't, but just in case: wake all, not just one. this.cond.signalAll(); } public void interrupt() { aborted = true; this.cond.signalAll(); } } // class WaitingThread ././@LongLink0100644 0000000 0000000 00000000172 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/WaitingThreadAborter.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/conn/tsccm/Wait0100644 0000000 0000000 00000004132 12301751664 032353 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn.tsccm; /** * A simple class that can interrupt a {@link WaitingThread}. * * Must be called with the pool lock held. * * @since 4.0 * * @deprecated (4.2) do not use */ @Deprecated public class WaitingThreadAborter { private WaitingThread waitingThread; private boolean aborted; /** * If a waiting thread has been set, interrupts it. */ public void abort() { aborted = true; if (waitingThread != null) { waitingThread.interrupt(); } } /** * Sets the waiting thread. If this has already been aborted, * the waiting thread is immediately interrupted. * * @param waitingThread The thread to interrupt when aborting. */ public void setWaitingThread(final WaitingThread waitingThread) { this.waitingThread = waitingThread; if (aborted) { waitingThread.interrupt(); } } } httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/cookie/0040755 0000000 0000000 00000000000 12301751666 030734 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000153 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/cookie/DateUtils.javahttpcomponents-client-4.3.3/httpclient/src/main/java-deprecated/org/apache/http/impl/cookie/DateUtil0100644 0000000 0000000 00000012555 12301751666 032377 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Date; import java.util.TimeZone; import org.apache.http.annotation.Immutable; /** * A utility class for parsing and formatting HTTP dates as used in cookies and * other headers. This class handles dates as defined by RFC 2616 section * 3.3.1 as well as some other common non-standard formats. * * * @since 4.0 * * @deprecated (4.3) Use {@link org.apache.http.client.utils.DateUtils}. */ @Deprecated @Immutable public final class DateUtils { /** * Date format pattern used to parse HTTP date headers in RFC 1123 format. */ public static final String PATTERN_RFC1123 = org.apache.http.client.utils.DateUtils.PATTERN_RFC1123; /** * Date format pattern used to parse HTTP date headers in RFC 1036 format. */ public static final String PATTERN_RFC1036 = org.apache.http.client.utils.DateUtils.PATTERN_RFC1036; /** * Date format pattern used to parse HTTP date headers in ANSI C * asctime() format. */ public static final String PATTERN_ASCTIME = org.apache.http.client.utils.DateUtils.PATTERN_ASCTIME; public static final TimeZone GMT = TimeZone.getTimeZone("GMT"); /** * Parses a date value. The formats used for parsing the date value are retrieved from * the default http params. * * @param dateValue the date value to parse * * @return the parsed date * * @throws DateParseException if the value could not be parsed using any of the * supported date formats */ public static Date parseDate(final String dateValue) throws DateParseException { return parseDate(dateValue, null, null); } /** * Parses the date value using the given date formats. * * @param dateValue the date value to parse * @param dateFormats the date formats to use * * @return the parsed date * * @throws DateParseException if none of the dataFormats could parse the dateValue */ public static Date parseDate(final String dateValue, final String[] dateFormats) throws DateParseException { return parseDate(dateValue, dateFormats, null); } /** * Parses the date value using the given date formats. * * @param dateValue the date value to parse * @param dateFormats the date formats to use * @param startDate During parsing, two digit years will be placed in the range * startDate to startDate + 100 years. This value may * be null. When null is given as a parameter, year * 2000 will be used. * * @return the parsed date * * @throws DateParseException if none of the dataFormats could parse the dateValue */ public static Date parseDate( final String dateValue, final String[] dateFormats, final Date startDate ) throws DateParseException { final Date d = org.apache.http.client.utils.DateUtils.parseDate(dateValue, dateFormats, startDate); if (d == null) { throw new DateParseException("Unable to parse the date " + dateValue); } return d; } /** * Formats the given date according to the RFC 1123 pattern. * * @param date The date to format. * @return An RFC 1123 formatted date string. * * @see #PATTERN_RFC1123 */ public static String formatDate(final Date date) { return org.apache.http.client.utils.DateUtils.formatDate(date); } /** * Formats the given date according to the specified pattern. The pattern * must conform to that used by the {@link java.text.SimpleDateFormat simple * date format} class. * * @param date The date to format. * @param pattern The pattern to use for formatting the date. * @return A formatted date string. * * @throws IllegalArgumentException If the given date pattern is invalid. * * @see java.text.SimpleDateFormat */ public static String formatDate(final Date date, final String pattern) { return org.apache.http.client.utils.DateUtils.formatDate(date, pattern); } /** This class should not be instantiated. */ private DateUtils() { } } httpcomponents-client-4.3.3/httpclient/src/main/resources/0040755 0000000 0000000 00000000000 12301751660 022520 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/resources/org/0040755 0000000 0000000 00000000000 12301751660 023307 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/resources/org/apache/0040755 0000000 0000000 00000000000 12301751660 024530 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/resources/org/apache/http/0040755 0000000 0000000 00000000000 12301751660 025507 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/resources/org/apache/http/client/0040755 0000000 0000000 00000000000 12301751660 026765 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/main/resources/org/apache/http/client/version.properties0100644 0000000 0000000 00000001626 12301751660 032572 0ustar000000000 0000000 # # 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. # info.module = HttpClient info.release = ${pom.version} info.timestamp = ${mvn.timestamp} # timestamp requires Maven 2.1 httpcomponents-client-4.3.3/httpclient/src/test/0040755 0000000 0000000 00000000000 12301751660 020541 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/0040755 0000000 0000000 00000000000 12301751653 021464 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/0040755 0000000 0000000 00000000000 12301751653 022253 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/0040755 0000000 0000000 00000000000 12301751653 023474 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/0040755 0000000 0000000 00000000000 12301751660 024451 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/auth/0040755 0000000 0000000 00000000000 12301751655 025416 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/auth/TestCredentials.java0100644 0000000 0000000 00000025027 12301751655 031361 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.auth; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.junit.Assert; import org.junit.Test; public class TestCredentials { @Test public void testUsernamePasswordCredentialsBasics() { final UsernamePasswordCredentials creds1 = new UsernamePasswordCredentials( "name", "pwd"); Assert.assertEquals("name", creds1.getUserName()); Assert.assertEquals(new BasicUserPrincipal("name"), creds1.getUserPrincipal()); Assert.assertEquals("pwd", creds1.getPassword()); Assert.assertEquals("[principal: name]", creds1.toString()); final UsernamePasswordCredentials creds2 = new UsernamePasswordCredentials( "name:pwd"); Assert.assertEquals("name", creds2.getUserName()); Assert.assertEquals(new BasicUserPrincipal("name"), creds2.getUserPrincipal()); Assert.assertEquals("pwd", creds2.getPassword()); Assert.assertEquals("[principal: name]", creds2.toString()); final UsernamePasswordCredentials creds3 = new UsernamePasswordCredentials( "name"); Assert.assertEquals("name", creds3.getUserName()); Assert.assertEquals(new BasicUserPrincipal("name"), creds3.getUserPrincipal()); Assert.assertEquals(null, creds3.getPassword()); Assert.assertEquals("[principal: name]", creds3.toString()); } @Test public void testNTCredentialsBasics() { final NTCredentials creds1 = new NTCredentials( "name", "pwd", "localhost", "domain"); Assert.assertEquals("name", creds1.getUserName()); Assert.assertEquals(new NTUserPrincipal("DOMAIN", "name"), creds1.getUserPrincipal()); Assert.assertEquals("pwd", creds1.getPassword()); Assert.assertEquals("[principal: DOMAIN\\name][workstation: LOCALHOST]", creds1.toString()); final NTCredentials creds2 = new NTCredentials( "name", null, null, null); Assert.assertEquals("name", creds2.getUserName()); Assert.assertEquals(new NTUserPrincipal(null, "name"), creds2.getUserPrincipal()); Assert.assertEquals(null, creds2.getPassword()); Assert.assertEquals("[principal: name][workstation: null]", creds2.toString()); final NTCredentials creds3 = new NTCredentials( "domain/name:pwd"); Assert.assertEquals("name", creds3.getUserName()); Assert.assertEquals(new NTUserPrincipal("DOMAIN", "name"), creds3.getUserPrincipal()); Assert.assertEquals("pwd", creds3.getPassword()); Assert.assertEquals("[principal: DOMAIN\\name][workstation: null]", creds3.toString()); final NTCredentials creds4 = new NTCredentials( "domain/name"); Assert.assertEquals("name", creds4.getUserName()); Assert.assertEquals(new NTUserPrincipal("DOMAIN", "name"), creds4.getUserPrincipal()); Assert.assertEquals(null, creds4.getPassword()); Assert.assertEquals("[principal: DOMAIN\\name][workstation: null]", creds4.toString()); final NTCredentials creds5 = new NTCredentials( "name"); Assert.assertEquals("name", creds5.getUserName()); Assert.assertEquals(new NTUserPrincipal(null, "name"), creds5.getUserPrincipal()); Assert.assertEquals(null, creds5.getPassword()); Assert.assertEquals("[principal: name][workstation: null]", creds5.toString()); } @Test public void testUsernamePasswordCredentialsHashCode() { final UsernamePasswordCredentials creds1 = new UsernamePasswordCredentials( "name", "pwd"); final UsernamePasswordCredentials creds2 = new UsernamePasswordCredentials( "othername", "pwd"); final UsernamePasswordCredentials creds3 = new UsernamePasswordCredentials( "name", "otherpwd"); Assert.assertTrue(creds1.hashCode() == creds1.hashCode()); Assert.assertTrue(creds1.hashCode() != creds2.hashCode()); Assert.assertTrue(creds1.hashCode() == creds3.hashCode()); } @Test public void testUsernamePasswordCredentialsEquals() { final UsernamePasswordCredentials creds1 = new UsernamePasswordCredentials( "name", "pwd"); final UsernamePasswordCredentials creds2 = new UsernamePasswordCredentials( "othername", "pwd"); final UsernamePasswordCredentials creds3 = new UsernamePasswordCredentials( "name", "otherpwd"); Assert.assertTrue(creds1.equals(creds1)); Assert.assertFalse(creds1.equals(creds2)); Assert.assertTrue(creds1.equals(creds3)); } @Test public void testNTCredentialsHashCode() { final NTCredentials creds1 = new NTCredentials( "name", "pwd", "somehost", "domain"); final NTCredentials creds2 = new NTCredentials( "othername", "pwd", "somehost", "domain"); final NTCredentials creds3 = new NTCredentials( "name", "otherpwd", "SomeHost", "Domain"); final NTCredentials creds4 = new NTCredentials( "name", "pwd", "otherhost", "domain"); final NTCredentials creds5 = new NTCredentials( "name", "pwd", null, "domain"); final NTCredentials creds6 = new NTCredentials( "name", "pwd", "somehost", "ms"); final NTCredentials creds7 = new NTCredentials( "name", "pwd", "somehost", null); final NTCredentials creds8 = new NTCredentials( "name", "pwd", null, "domain"); final NTCredentials creds9 = new NTCredentials( "name", "pwd", "somehost", null); Assert.assertTrue(creds1.hashCode() == creds1.hashCode()); Assert.assertTrue(creds1.hashCode() != creds2.hashCode()); Assert.assertTrue(creds1.hashCode() == creds3.hashCode()); Assert.assertFalse(creds1.hashCode() == creds4.hashCode()); Assert.assertFalse(creds1.hashCode() == creds5.hashCode()); Assert.assertFalse(creds1.hashCode() == creds6.hashCode()); Assert.assertFalse(creds1.hashCode() == creds7.hashCode()); Assert.assertTrue(creds8.hashCode() == creds5.hashCode()); Assert.assertTrue(creds9.hashCode() == creds7.hashCode()); } @Test public void testNTCredentialsEquals() { final NTCredentials creds1 = new NTCredentials( "name", "pwd", "somehost", "domain"); final NTCredentials creds2 = new NTCredentials( "othername", "pwd", "somehost", "domain"); final NTCredentials creds3 = new NTCredentials( "name", "otherpwd", "SomeHost", "Domain"); final NTCredentials creds4 = new NTCredentials( "name", "pwd", "otherhost", "domain"); final NTCredentials creds5 = new NTCredentials( "name", "pwd", null, "domain"); final NTCredentials creds6 = new NTCredentials( "name", "pwd", "somehost", "ms"); final NTCredentials creds7 = new NTCredentials( "name", "pwd", "somehost", null); final NTCredentials creds8 = new NTCredentials( "name", "pwd", null, "domain"); final NTCredentials creds9 = new NTCredentials( "name", "pwd", "somehost", null); Assert.assertTrue(creds1.equals(creds1)); Assert.assertFalse(creds1.equals(creds2)); Assert.assertTrue(creds1.equals(creds3)); Assert.assertFalse(creds1.equals(creds4)); Assert.assertFalse(creds1.equals(creds5)); Assert.assertFalse(creds1.equals(creds6)); Assert.assertFalse(creds1.equals(creds7)); Assert.assertTrue(creds8.equals(creds5)); Assert.assertTrue(creds9.equals(creds7)); } @Test public void testUsernamePasswordCredentialsSerialization() throws Exception { final UsernamePasswordCredentials orig = new UsernamePasswordCredentials("name", "pwd"); final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream(); final ObjectOutputStream outstream = new ObjectOutputStream(outbuffer); outstream.writeObject(orig); outstream.close(); final byte[] raw = outbuffer.toByteArray(); final ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw); final ObjectInputStream instream = new ObjectInputStream(inbuffer); final UsernamePasswordCredentials clone = (UsernamePasswordCredentials) instream.readObject(); Assert.assertEquals(orig, clone); } @Test public void testNTCredentialsSerialization() throws Exception { final NTCredentials orig = new NTCredentials("name", "pwd", "somehost", "domain"); final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream(); final ObjectOutputStream outstream = new ObjectOutputStream(outbuffer); outstream.writeObject(orig); outstream.close(); final byte[] raw = outbuffer.toByteArray(); final ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw); final ObjectInputStream instream = new ObjectInputStream(inbuffer); final NTCredentials clone = (NTCredentials) instream.readObject(); Assert.assertEquals(orig, clone); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/0040755 0000000 0000000 00000000000 12301751655 025733 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/config/0040755 0000000 0000000 00000000000 12301751655 027200 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/config/TestRequestConfig.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/config/TestRequestConfig0100644 0000000 0000000 00000011271 12301751655 032540 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.config; import junit.framework.Assert; import org.apache.http.HttpHost; import org.junit.Test; import java.net.InetAddress; import java.util.Arrays; public class TestRequestConfig { @Test public void testBasics() { final RequestConfig config = RequestConfig.custom().build(); config.toString(); } @Test public void testDefaults() { final RequestConfig config = RequestConfig.DEFAULT; Assert.assertEquals(-1, config.getSocketTimeout()); Assert.assertEquals(-1, config.getConnectTimeout()); Assert.assertEquals(-1, config.getConnectionRequestTimeout()); Assert.assertEquals(false, config.isExpectContinueEnabled()); Assert.assertEquals(true, config.isStaleConnectionCheckEnabled()); Assert.assertEquals(true, config.isAuthenticationEnabled()); Assert.assertEquals(true, config.isRedirectsEnabled()); Assert.assertEquals(true, config.isRelativeRedirectsAllowed()); Assert.assertEquals(false, config.isCircularRedirectsAllowed()); Assert.assertEquals(50, config.getMaxRedirects()); Assert.assertEquals(null, config.getCookieSpec()); Assert.assertEquals(null, config.getLocalAddress()); Assert.assertEquals(null, config.getProxy()); Assert.assertEquals(null, config.getTargetPreferredAuthSchemes()); Assert.assertEquals(null, config.getProxyPreferredAuthSchemes()); } @Test public void testBuildAndCopy() throws Exception { final RequestConfig config0 = RequestConfig.custom() .setSocketTimeout(22) .setConnectTimeout(33) .setConnectionRequestTimeout(44) .setExpectContinueEnabled(true) .setStaleConnectionCheckEnabled(false) .setAuthenticationEnabled(false) .setRedirectsEnabled(false) .setRelativeRedirectsAllowed(false) .setCircularRedirectsAllowed(true) .setMaxRedirects(100) .setCookieSpec(CookieSpecs.STANDARD) .setLocalAddress(InetAddress.getLocalHost()) .setProxy(new HttpHost("someproxy")) .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM)) .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.DIGEST)) .build(); final RequestConfig config = RequestConfig.copy(config0).build(); Assert.assertEquals(22, config.getSocketTimeout()); Assert.assertEquals(33, config.getConnectTimeout()); Assert.assertEquals(44, config.getConnectionRequestTimeout()); Assert.assertEquals(true, config.isExpectContinueEnabled()); Assert.assertEquals(false, config.isStaleConnectionCheckEnabled()); Assert.assertEquals(false, config.isAuthenticationEnabled()); Assert.assertEquals(false, config.isRedirectsEnabled()); Assert.assertEquals(false, config.isRelativeRedirectsAllowed()); Assert.assertEquals(true, config.isCircularRedirectsAllowed()); Assert.assertEquals(100, config.getMaxRedirects()); Assert.assertEquals(CookieSpecs.STANDARD, config.getCookieSpec()); Assert.assertEquals(InetAddress.getLocalHost(), config.getLocalAddress()); Assert.assertEquals(new HttpHost("someproxy"), config.getProxy()); Assert.assertEquals(Arrays.asList(AuthSchemes.NTLM), config.getTargetPreferredAuthSchemes()); Assert.assertEquals(Arrays.asList(AuthSchemes.DIGEST), config.getProxyPreferredAuthSchemes()); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/entity/0040755 0000000 0000000 00000000000 12301751655 027247 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000160 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/entity/TestDecompressingEntity.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/entity/TestDecompressing0100644 0000000 0000000 00000010066 12301751655 032634 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.entity; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.CRC32; import java.util.zip.CheckedInputStream; import java.util.zip.Checksum; import org.apache.http.HttpEntity; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Test; public class TestDecompressingEntity { @Test public void testNonStreaming() throws Exception { final CRC32 crc32 = new CRC32(); final StringEntity wrapped = new StringEntity("1234567890", "ASCII"); final ChecksumEntity entity = new ChecksumEntity(wrapped, crc32); Assert.assertFalse(entity.isStreaming()); final String s = EntityUtils.toString(entity); Assert.assertEquals("1234567890", s); Assert.assertEquals(639479525L, crc32.getValue()); final InputStream in1 = entity.getContent(); final InputStream in2 = entity.getContent(); Assert.assertTrue(in1 != in2); } @Test public void testStreaming() throws Exception { final CRC32 crc32 = new CRC32(); final ByteArrayInputStream in = new ByteArrayInputStream("1234567890".getBytes("ASCII")); final InputStreamEntity wrapped = new InputStreamEntity(in, -1); final ChecksumEntity entity = new ChecksumEntity(wrapped, crc32); Assert.assertTrue(entity.isStreaming()); final String s = EntityUtils.toString(entity); Assert.assertEquals("1234567890", s); Assert.assertEquals(639479525L, crc32.getValue()); final InputStream in1 = entity.getContent(); final InputStream in2 = entity.getContent(); Assert.assertTrue(in1 == in2); EntityUtils.consume(entity); EntityUtils.consume(entity); } @Test public void testWriteToStream() throws Exception { final CRC32 crc32 = new CRC32(); final StringEntity wrapped = new StringEntity("1234567890", "ASCII"); final ChecksumEntity entity = new ChecksumEntity(wrapped, crc32); Assert.assertFalse(entity.isStreaming()); final ByteArrayOutputStream out = new ByteArrayOutputStream(); entity.writeTo(out); final String s = new String(out.toByteArray(), "ASCII"); Assert.assertEquals("1234567890", s); Assert.assertEquals(639479525L, crc32.getValue()); } static class ChecksumEntity extends DecompressingEntity { private final Checksum checksum; public ChecksumEntity(final HttpEntity wrapped, final Checksum checksum) { super(wrapped); this.checksum = checksum; } @Override InputStream decorate(final InputStream wrapped) throws IOException { return new CheckedInputStream(wrapped, this.checksum); } } } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/entity/TestEntityBuilder.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/entity/TestEntityBuilder0100644 0000000 0000000 00000012273 12301751655 032617 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.entity; import java.io.File; import java.io.InputStream; import org.apache.http.HttpEntity; import org.apache.http.entity.ContentType; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; public class TestEntityBuilder { @Test(expected=IllegalStateException.class) public void testBuildEmptyEntity() throws Exception { final HttpEntity entity = EntityBuilder.create().build(); Assert.assertNotNull(entity); entity.getContent(); } @Test public void testBuildTextEntity() throws Exception { final HttpEntity entity = EntityBuilder.create().setText("stuff").build(); Assert.assertNotNull(entity); Assert.assertNotNull(entity.getContent()); Assert.assertNotNull(entity.getContentType()); Assert.assertEquals("text/plain; charset=ISO-8859-1", entity.getContentType().getValue()); } @Test public void testBuildBinaryEntity() throws Exception { final HttpEntity entity = EntityBuilder.create().setBinary(new byte[] {0, 1, 2}).build(); Assert.assertNotNull(entity); Assert.assertNotNull(entity.getContent()); Assert.assertNotNull(entity.getContentType()); Assert.assertEquals("application/octet-stream", entity.getContentType().getValue()); } @Test public void testBuildStreamEntity() throws Exception { final InputStream in = Mockito.mock(InputStream.class); final HttpEntity entity = EntityBuilder.create().setStream(in).build(); Assert.assertNotNull(entity); Assert.assertNotNull(entity.getContent()); Assert.assertNotNull(entity.getContentType()); Assert.assertEquals("application/octet-stream", entity.getContentType().getValue()); } @Test public void testBuildSerializableEntity() throws Exception { final HttpEntity entity = EntityBuilder.create().setSerializable(Boolean.TRUE).build(); Assert.assertNotNull(entity); Assert.assertNotNull(entity.getContent()); Assert.assertNotNull(entity.getContentType()); Assert.assertEquals("application/octet-stream", entity.getContentType().getValue()); } @Test public void testBuildFileEntity() throws Exception { final File file = new File("stuff"); final HttpEntity entity = EntityBuilder.create().setFile(file).build(); Assert.assertNotNull(entity); Assert.assertNotNull(entity.getContentType()); Assert.assertEquals("application/octet-stream", entity.getContentType().getValue()); } @Test public void testExplicitContentProperties() throws Exception { final HttpEntity entity = EntityBuilder.create() .setContentType(ContentType.APPLICATION_JSON) .setContentEncoding("identity") .setBinary(new byte[] {0, 1, 2}) .setText("{\"stuff\"}").build(); Assert.assertNotNull(entity); Assert.assertNotNull(entity.getContentType()); Assert.assertEquals("application/json; charset=UTF-8", entity.getContentType().getValue()); Assert.assertNotNull(entity.getContentEncoding()); Assert.assertEquals("identity", entity.getContentEncoding().getValue()); Assert.assertEquals("{\"stuff\"}", EntityUtils.toString(entity)); } @Test public void testBuildChunked() throws Exception { final HttpEntity entity = EntityBuilder.create().setText("stuff").chunked().build(); Assert.assertNotNull(entity); Assert.assertTrue(entity.isChunked()); } @Test public void testBuildGZipped() throws Exception { final HttpEntity entity = EntityBuilder.create().setText("stuff").gzipCompress().build(); Assert.assertNotNull(entity); Assert.assertNotNull(entity.getContentType()); Assert.assertEquals("text/plain; charset=ISO-8859-1", entity.getContentType().getValue()); Assert.assertNotNull(entity.getContentEncoding()); Assert.assertEquals("gzip", entity.getContentEncoding().getValue()); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/entity/TestGZip.java0100644 0000000 0000000 00000007361 12301751655 031627 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.entity; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.http.Consts; import org.apache.http.HttpEntity; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.ContentType; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Test; public class TestGZip { @Test public void testBasic() throws Exception { final String s = "some kind of text"; final StringEntity e = new StringEntity(s, ContentType.TEXT_PLAIN); e.setChunked(false); final GzipCompressingEntity gzipe = new GzipCompressingEntity(e); Assert.assertTrue(gzipe.isChunked()); Assert.assertEquals(-1, gzipe.getContentLength()); Assert.assertNotNull(gzipe.getContentEncoding()); Assert.assertEquals("gzip", gzipe.getContentEncoding().getValue()); } @Test public void testCompressionDecompression() throws Exception { final StringEntity in = new StringEntity("some kind of text", ContentType.TEXT_PLAIN); final GzipCompressingEntity gzipe = new GzipCompressingEntity(in); final ByteArrayOutputStream buf = new ByteArrayOutputStream(); gzipe.writeTo(buf); final ByteArrayEntity out = new ByteArrayEntity(buf.toByteArray()); final GzipDecompressingEntity gunzipe = new GzipDecompressingEntity(out); Assert.assertEquals("some kind of text", EntityUtils.toString(gunzipe, Consts.ASCII)); } @Test public void testGzipDecompressingEntityDoesNotCrashInConstructorAndLeaveInputStreamOpen() throws Exception { final AtomicBoolean inputStreamIsClosed = new AtomicBoolean(false); final HttpEntity in = new InputStreamEntity(new InputStream() { @Override public int read() throws IOException { throw new IOException("An exception occurred"); } @Override public void close() throws IOException { inputStreamIsClosed.set(true); } }, 123); final GzipDecompressingEntity gunzipe = new GzipDecompressingEntity(in); try { gunzipe.getContent(); } catch (final IOException e) { // As I cannot get the content, GzipDecompressingEntity is supposed // to have released everything Assert.assertTrue(inputStreamIsClosed.get()); } } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/methods/0040755 0000000 0000000 00000000000 12301751654 027375 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/methods/TestHttpOptions.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/methods/TestHttpOptions.0100644 0000000 0000000 00000004024 12301751654 032526 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.util.Set; import org.apache.http.ProtocolVersion; import org.apache.http.message.BasicHttpResponse; import org.apache.http.message.BasicStatusLine; import org.junit.Assert; import org.junit.Test; public class TestHttpOptions { @Test public void testMultipleAllows() { final ProtocolVersion proto = new ProtocolVersion("HTTP", 1, 1); final BasicStatusLine line = new BasicStatusLine(proto, 200, "test reason"); final BasicHttpResponse resp = new BasicHttpResponse(line); resp.addHeader("Allow", "POST"); resp.addHeader("Allow", "GET"); final HttpOptions opt = new HttpOptions(); final Set methodsName = opt.getAllowedMethods(resp); Assert.assertTrue(methodsName.contains("POST")); Assert.assertTrue(methodsName.contains("GET")); } } ././@LongLink0100644 0000000 0000000 00000000155 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/methods/TestHttpRequestBase.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/methods/TestHttpRequestB0100644 0000000 0000000 00000010174 12301751654 032552 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.io.ByteArrayInputStream; import org.apache.http.Header; import org.apache.http.HttpVersion; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.util.LangUtils; import org.junit.Assert; import org.junit.Test; public class TestHttpRequestBase { @Test public void testBasicProperties() throws Exception { final HttpGet httpget = new HttpGet("http://host/path"); Assert.assertEquals("GET", httpget.getRequestLine().getMethod()); Assert.assertEquals("http://host/path", httpget.getRequestLine().getUri()); Assert.assertEquals(HttpVersion.HTTP_1_1, httpget.getRequestLine().getProtocolVersion()); } @Test public void testEmptyURI() throws Exception { final HttpGet httpget = new HttpGet(""); Assert.assertEquals("/", httpget.getRequestLine().getUri()); } @Test public void testCloneBasicRequests() throws Exception { final HttpGet httpget = new HttpGet("http://host/path"); httpget.addHeader("h1", "this header"); httpget.addHeader("h2", "that header"); httpget.addHeader("h3", "all sorts of headers"); final HttpGet clone = (HttpGet) httpget.clone(); Assert.assertEquals(httpget.getMethod(), clone.getMethod()); Assert.assertEquals(httpget.getURI(), clone.getURI()); final Header[] headers1 = httpget.getAllHeaders(); final Header[] headers2 = clone.getAllHeaders(); Assert.assertTrue(LangUtils.equals(headers1, headers2)); } @Test public void testCloneEntityEnclosingRequests() throws Exception { final HttpPost httppost = new HttpPost("http://host/path"); httppost.addHeader("h1", "this header"); httppost.addHeader("h2", "that header"); httppost.addHeader("h3", "all sorts of headers"); HttpPost clone = (HttpPost) httppost.clone(); Assert.assertEquals(httppost.getMethod(), clone.getMethod()); Assert.assertEquals(httppost.getURI(), clone.getURI()); final Header[] headers1 = httppost.getAllHeaders(); final Header[] headers2 = clone.getAllHeaders(); Assert.assertTrue(LangUtils.equals(headers1, headers2)); Assert.assertNull(clone.getEntity()); final StringEntity e1 = new StringEntity("stuff"); httppost.setEntity(e1); clone = (HttpPost) httppost.clone(); Assert.assertTrue(clone.getEntity() instanceof StringEntity); Assert.assertFalse(clone.getEntity().equals(e1)); } @Test(expected=CloneNotSupportedException.class) public void testCloneStreamingEntityEnclosingRequests() throws Exception { final ByteArrayInputStream instream = new ByteArrayInputStream(new byte[] {}); final InputStreamEntity e2 = new InputStreamEntity(instream, -1); final HttpPost httppost = new HttpPost("http://host/path"); httppost.setEntity(e2); httppost.clone(); } } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/methods/TestRequestBuilder.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/methods/TestRequestBuild0100644 0000000 0000000 00000022076 12301751654 032574 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.methods; import java.net.URI; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpVersion; import org.apache.http.client.config.RequestConfig; import org.apache.http.entity.BasicHttpEntity; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Test; public class TestRequestBuilder { @Test public void testBasicGet() throws Exception { final HttpUriRequest request = RequestBuilder.get().build(); Assert.assertNotNull(request); Assert.assertEquals("GET", request.getMethod()); Assert.assertEquals(URI.create("/"), request.getURI()); Assert.assertEquals(HttpVersion.HTTP_1_1, request.getProtocolVersion()); Assert.assertFalse(request instanceof HttpEntityEnclosingRequest); } @Test public void testArbitraryMethod() throws Exception { final HttpUriRequest request = RequestBuilder.create("Whatever").build(); Assert.assertNotNull(request); Assert.assertEquals("Whatever", request.getMethod()); Assert.assertEquals(URI.create("/"), request.getURI()); Assert.assertEquals(HttpVersion.HTTP_1_1, request.getProtocolVersion()); } @Test public void testBasicWithEntity() throws Exception { final HttpEntity entity = new BasicHttpEntity(); final HttpUriRequest request = RequestBuilder.post().setEntity(entity).build(); Assert.assertNotNull(request); Assert.assertEquals("POST", request.getMethod()); Assert.assertEquals(URI.create("/"), request.getURI()); Assert.assertEquals(HttpVersion.HTTP_1_1, request.getProtocolVersion()); Assert.assertTrue(request instanceof HttpEntityEnclosingRequest); Assert.assertSame(entity, ((HttpEntityEnclosingRequest) request).getEntity()); } @Test public void testGetWithEntity() throws Exception { final HttpEntity entity = new BasicHttpEntity(); final HttpUriRequest request = RequestBuilder.get().setEntity(entity).build(); Assert.assertNotNull(request); Assert.assertEquals("GET", request.getMethod()); Assert.assertEquals(URI.create("/"), request.getURI()); Assert.assertEquals(HttpVersion.HTTP_1_1, request.getProtocolVersion()); Assert.assertTrue(request instanceof HttpEntityEnclosingRequest); Assert.assertSame(entity, ((HttpEntityEnclosingRequest) request).getEntity()); } @Test public void testAddParameters1() throws Exception { final HttpUriRequest request = RequestBuilder.get() .addParameter("p1", "this") .addParameter("p2", "that") .build(); Assert.assertFalse(request instanceof HttpEntityEnclosingRequest); Assert.assertEquals(new URI("/?p1=this&p2=that"), request.getURI()); } @Test public void testAddParameters2() throws Exception { final HttpUriRequest request = RequestBuilder.get() .addParameter("p1", "this") .addParameters(new BasicNameValuePair("p2", "that")) .build(); Assert.assertFalse(request instanceof HttpEntityEnclosingRequest); Assert.assertEquals(new URI("/?p1=this&p2=that"), request.getURI()); } @Test public void testAddParameters3() throws Exception { final HttpUriRequest request = RequestBuilder.post() .addParameter("p1", "this") .addParameter("p2", "that") .build(); Assert.assertTrue(request instanceof HttpEntityEnclosingRequest); final HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity(); Assert.assertNotNull(entity); Assert.assertEquals(new URI("/"), request.getURI()); Assert.assertEquals("p1=this&p2=that", EntityUtils.toString(entity)); } @Test public void testAddParameters4() throws Exception { final HttpUriRequest request = RequestBuilder.post() .setUri("http://targethost/?blah") .addParameter("p1", "this") .addParameter("p2", "that") .setEntity(new StringEntity("blah")) .build(); Assert.assertTrue(request instanceof HttpEntityEnclosingRequest); Assert.assertEquals(new URI("http://targethost/?blah&p1=this&p2=that"), request.getURI()); } @Test public void testCopy() throws Exception { final HttpEntity entity = new StringEntity("stuff"); final RequestConfig config = RequestConfig.custom().build(); final HttpUriRequest request = RequestBuilder.put() .setUri(URI.create("/stuff")) .setVersion(HttpVersion.HTTP_1_0) .addHeader("header1", "stuff") .setHeader("header2", "more stuff") .setEntity(entity) .setConfig(config) .build(); Assert.assertNotNull(request); Assert.assertEquals("PUT", request.getMethod()); Assert.assertEquals(URI.create("/stuff"), request.getURI()); Assert.assertEquals(HttpVersion.HTTP_1_0, request.getProtocolVersion()); Assert.assertTrue(request instanceof HttpEntityEnclosingRequest); final HttpUriRequest copy = RequestBuilder.copy(request).setUri("/other-stuff").build(); Assert.assertEquals("PUT", copy.getMethod()); Assert.assertEquals(URI.create("/other-stuff"), copy.getURI()); Assert.assertTrue(copy instanceof HttpEntityEnclosingRequest); Assert.assertSame(entity, ((HttpEntityEnclosingRequest) copy).getEntity()); Assert.assertTrue(copy instanceof Configurable); Assert.assertSame(config, ((Configurable) copy).getConfig()); } @Test public void testGettersAndMutators() throws Exception { final HttpEntity entity = new StringEntity("stuff"); final RequestConfig config = RequestConfig.custom().build(); final Header h1 = new BasicHeader("header1", "stuff"); final Header h2 = new BasicHeader("header1", "more-stuff"); final RequestBuilder builder = RequestBuilder.put() .setUri("/stuff") .setVersion(HttpVersion.HTTP_1_0) .addHeader(h1) .addHeader(h2) .setEntity(entity) .setConfig(config); Assert.assertEquals("PUT", builder.getMethod()); Assert.assertEquals(URI.create("/stuff"), builder.getUri()); Assert.assertEquals(HttpVersion.HTTP_1_0, builder.getVersion()); Assert.assertSame(h1, builder.getFirstHeader("header1")); Assert.assertSame(h2, builder.getLastHeader("header1")); Assert.assertEquals(2, builder.getHeaders("header1").length); Assert.assertSame(entity, builder.getEntity()); Assert.assertSame(config, builder.getConfig()); builder.setUri((String) null) .setVersion(null) .removeHeader(h1) .removeHeaders("header1") .removeHeader(h2) .setEntity(null) .setConfig(null); Assert.assertEquals(null, builder.getUri()); Assert.assertEquals(null, builder.getVersion()); Assert.assertSame(null, builder.getFirstHeader("header1")); Assert.assertSame(null, builder.getLastHeader("header1")); Assert.assertEquals(0, builder.getHeaders("header1").length); Assert.assertSame(null, builder.getEntity()); Assert.assertSame(null, builder.getConfig()); builder.setHeader(h2) .setHeader("header1", "a-lot-more-stuff"); Assert.assertSame("a-lot-more-stuff", builder.getLastHeader("header1").getValue()); Assert.assertEquals(1, builder.getHeaders("header1").length); } @Test(expected=IllegalArgumentException.class) public void testCopyNull() throws Exception { RequestBuilder.copy(null); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/0040755 0000000 0000000 00000000000 12301751654 027573 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestRequestAcceptEncoding.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestRequestAcce0100644 0000000 0000000 00000005133 12301751654 032561 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.junit.Assert; import org.junit.Test; public class TestRequestAcceptEncoding { @Test public void testAcceptEncoding() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpContext context = new BasicHttpContext(); final HttpRequestInterceptor interceptor = new RequestAcceptEncoding(); interceptor.process(request, context); final Header header = request.getFirstHeader("Accept-Encoding"); Assert.assertNotNull(header); Assert.assertEquals("gzip,deflate", header.getValue()); } @Test public void testAcceptEncodingAlreadyPResent() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); request.addHeader("Accept-Encoding", "stuff"); final HttpContext context = new BasicHttpContext(); final HttpRequestInterceptor interceptor = new RequestAcceptEncoding(); interceptor.process(request, context); final Header header = request.getFirstHeader("Accept-Encoding"); Assert.assertNotNull(header); Assert.assertEquals("stuff", header.getValue()); } } ././@LongLink0100644 0000000 0000000 00000000160 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestRequestAddCookies.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestRequestAddC0100644 0000000 0000000 00000055536 12301751654 032535 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.util.Date; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.client.CookieStore; import org.apache.http.client.config.CookieSpecs; import org.apache.http.client.config.RequestConfig; import org.apache.http.config.Lookup; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.RouteInfo.LayerType; import org.apache.http.conn.routing.RouteInfo.TunnelType; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.CookieSpecProvider; import org.apache.http.cookie.SM; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.cookie.BasicClientCookie; import org.apache.http.impl.cookie.BasicClientCookie2; import org.apache.http.impl.cookie.BestMatchSpecFactory; import org.apache.http.impl.cookie.BrowserCompatSpec; import org.apache.http.impl.cookie.BrowserCompatSpecFactory; import org.apache.http.impl.cookie.IgnoreSpecFactory; import org.apache.http.impl.cookie.NetscapeDraftSpecFactory; import org.apache.http.impl.cookie.RFC2965SpecFactory; import org.apache.http.message.BasicHttpRequest; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestRequestAddCookies { private HttpHost target; private CookieStore cookieStore; private Lookup cookieSpecRegistry; @Before public void setUp() { this.target = new HttpHost("localhost.local", 80); this.cookieStore = new BasicCookieStore(); final BasicClientCookie2 cookie1 = new BasicClientCookie2("name1", "value1"); cookie1.setVersion(1); cookie1.setDomain("localhost.local"); cookie1.setPath("/"); this.cookieStore.addCookie(cookie1); final BasicClientCookie2 cookie2 = new BasicClientCookie2("name2", "value2"); cookie2.setVersion(1); cookie2.setDomain("localhost.local"); cookie2.setPath("/"); this.cookieStore.addCookie(cookie2); this.cookieSpecRegistry = RegistryBuilder.create() .register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory()) .register(CookieSpecs.STANDARD, new RFC2965SpecFactory()) .register(CookieSpecs.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory()) .register(CookieSpecs.NETSCAPE, new NetscapeDraftSpecFactory()) .register(CookieSpecs.IGNORE_COOKIES, new IgnoreSpecFactory()) .build(); } @Test(expected=IllegalArgumentException.class) public void testRequestParameterCheck() throws Exception { final HttpClientContext context = HttpClientContext.create(); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(null, context); } @Test(expected=IllegalArgumentException.class) public void testContextParameterCheck() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, null); } @Test public void testAddCookies() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpRoute route = new HttpRoute(this.target, null, false); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final Header[] headers1 = request.getHeaders(SM.COOKIE); Assert.assertNotNull(headers1); Assert.assertEquals(2, headers1.length); Assert.assertEquals("$Version=1; name1=\"value1\"", headers1[0].getValue()); Assert.assertEquals("$Version=1; name2=\"value2\"", headers1[1].getValue()); final Header[] headers2 = request.getHeaders(SM.COOKIE2); Assert.assertNotNull(headers2); Assert.assertEquals(0, headers2.length); final CookieOrigin cookieOrigin = context.getCookieOrigin(); Assert.assertNotNull(cookieOrigin); Assert.assertEquals(this.target.getHostName(), cookieOrigin.getHost()); Assert.assertEquals(this.target.getPort(), cookieOrigin.getPort()); Assert.assertEquals("/", cookieOrigin.getPath()); Assert.assertFalse(cookieOrigin.isSecure()); } @Test public void testCookiesForConnectRequest() throws Exception { final HttpRequest request = new BasicHttpRequest("CONNECT", "www.somedomain.com"); final HttpRoute route = new HttpRoute(this.target, null, false); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final Header[] headers1 = request.getHeaders(SM.COOKIE); Assert.assertNotNull(headers1); Assert.assertEquals(0, headers1.length); final Header[] headers2 = request.getHeaders(SM.COOKIE2); Assert.assertNotNull(headers2); Assert.assertEquals(0, headers2.length); } @Test public void testNoCookieStore() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpRoute route = new HttpRoute(this.target, null, false); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.COOKIE_STORE, null); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final Header[] headers1 = request.getHeaders(SM.COOKIE); Assert.assertNotNull(headers1); Assert.assertEquals(0, headers1.length); final Header[] headers2 = request.getHeaders(SM.COOKIE2); Assert.assertNotNull(headers2); Assert.assertEquals(0, headers2.length); } @Test public void testNoCookieSpecRegistry() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpRoute route = new HttpRoute(this.target, null, false); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, null); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final Header[] headers1 = request.getHeaders(SM.COOKIE); Assert.assertNotNull(headers1); Assert.assertEquals(0, headers1.length); final Header[] headers2 = request.getHeaders(SM.COOKIE2); Assert.assertNotNull(headers2); Assert.assertEquals(0, headers2.length); } @Test public void testNoTargetHost() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpRoute route = new HttpRoute(this.target, null, false); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, null); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final Header[] headers1 = request.getHeaders(SM.COOKIE); Assert.assertNotNull(headers1); Assert.assertEquals(0, headers1.length); final Header[] headers2 = request.getHeaders(SM.COOKIE2); Assert.assertNotNull(headers2); Assert.assertEquals(0, headers2.length); } @Test public void testNoHttpConnection() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_CONNECTION, null); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final Header[] headers1 = request.getHeaders(SM.COOKIE); Assert.assertNotNull(headers1); Assert.assertEquals(0, headers1.length); final Header[] headers2 = request.getHeaders(SM.COOKIE2); Assert.assertNotNull(headers2); Assert.assertEquals(0, headers2.length); } @Test public void testAddCookiesUsingExplicitCookieSpec() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final RequestConfig config = RequestConfig.custom() .setCookieSpec(CookieSpecs.BROWSER_COMPATIBILITY).build(); final HttpRoute route = new HttpRoute(this.target, null, false); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.REQUEST_CONFIG, config); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final CookieSpec cookieSpec = context.getCookieSpec(); Assert.assertTrue(cookieSpec instanceof BrowserCompatSpec); final Header[] headers1 = request.getHeaders(SM.COOKIE); Assert.assertNotNull(headers1); Assert.assertEquals(1, headers1.length); Assert.assertEquals("name1=value1; name2=value2", headers1[0].getValue()); } @Test public void testAuthScopeInvalidRequestURI() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "crap:"); final HttpRoute route = new HttpRoute(this.target, null, false); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); } @Test public void testAuthScopeRemotePortWhenDirect() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/stuff"); this.target = new HttpHost("localhost.local"); final HttpRoute route = new HttpRoute(new HttpHost("localhost.local", 1234), null, false); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final CookieOrigin cookieOrigin = context.getCookieOrigin(); Assert.assertNotNull(cookieOrigin); Assert.assertEquals(this.target.getHostName(), cookieOrigin.getHost()); Assert.assertEquals(1234, cookieOrigin.getPort()); Assert.assertEquals("/stuff", cookieOrigin.getPath()); Assert.assertFalse(cookieOrigin.isSecure()); } @Test public void testAuthDefaultHttpPortWhenProxy() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/stuff"); this.target = new HttpHost("localhost.local"); final HttpRoute route = new HttpRoute( new HttpHost("localhost.local", 80), null, new HttpHost("localhost", 8888), false); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final CookieOrigin cookieOrigin = context.getCookieOrigin(); Assert.assertNotNull(cookieOrigin); Assert.assertEquals(this.target.getHostName(), cookieOrigin.getHost()); Assert.assertEquals(80, cookieOrigin.getPort()); Assert.assertEquals("/stuff", cookieOrigin.getPath()); Assert.assertFalse(cookieOrigin.isSecure()); } @Test public void testAuthDefaultHttpsPortWhenProxy() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/stuff"); this.target = new HttpHost("localhost", -1, "https"); final HttpRoute route = new HttpRoute( new HttpHost("localhost", 443, "https"), null, new HttpHost("localhost", 8888), true, TunnelType.TUNNELLED, LayerType.LAYERED); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final CookieOrigin cookieOrigin = context.getCookieOrigin(); Assert.assertNotNull(cookieOrigin); Assert.assertEquals(this.target.getHostName(), cookieOrigin.getHost()); Assert.assertEquals(443, cookieOrigin.getPort()); Assert.assertEquals("/stuff", cookieOrigin.getPath()); Assert.assertTrue(cookieOrigin.isSecure()); } @Test public void testExcludeExpiredCookies() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final BasicClientCookie2 cookie3 = new BasicClientCookie2("name3", "value3"); cookie3.setVersion(1); cookie3.setDomain("localhost.local"); cookie3.setPath("/"); cookie3.setExpiryDate(new Date(System.currentTimeMillis() - (24 * 60 * 60 * 1000))); this.cookieStore.addCookie(cookie3); final HttpRoute route = new HttpRoute(this.target, null, false); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final Header[] headers1 = request.getHeaders(SM.COOKIE); Assert.assertNotNull(headers1); Assert.assertEquals(2, headers1.length); Assert.assertEquals("$Version=1; name1=\"value1\"", headers1[0].getValue()); Assert.assertEquals("$Version=1; name2=\"value2\"", headers1[1].getValue()); final Header[] headers2 = request.getHeaders(SM.COOKIE2); Assert.assertNotNull(headers2); Assert.assertEquals(0, headers2.length); } @Test public void testNoMatchingCookies() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); this.cookieStore.clear(); final BasicClientCookie cookie3 = new BasicClientCookie("name3", "value3"); cookie3.setDomain("www.somedomain.com"); cookie3.setPath("/"); this.cookieStore.addCookie(cookie3); final HttpRoute route = new HttpRoute(this.target, null, false); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final Header[] headers1 = request.getHeaders(SM.COOKIE); Assert.assertNotNull(headers1); Assert.assertEquals(0, headers1.length); final Header[] headers2 = request.getHeaders(SM.COOKIE2); Assert.assertNotNull(headers2); Assert.assertEquals(0, headers2.length); } // Helper method private BasicClientCookie makeCookie(final String name, final String value, final String domain, final String path) { final BasicClientCookie cookie = new BasicClientCookie(name, value); cookie.setDomain(domain); cookie.setPath(path); return cookie; } @Test // Test for ordering adapted from test in Commons HC 3.1 public void testCookieOrder() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/foobar/yada/yada"); this.cookieStore.clear(); cookieStore.addCookie(makeCookie("nomatch", "value", "localhost.local", "/noway")); cookieStore.addCookie(makeCookie("name2", "value", "localhost.local", "/foobar/yada")); cookieStore.addCookie(makeCookie("name3", "value", "localhost.local", "/foobar")); cookieStore.addCookie(makeCookie("name1", "value", "localhost.local", "/foobar/yada/yada")); final HttpRoute route = new HttpRoute(this.target, null, false); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final Header[] headers1 = request.getHeaders(SM.COOKIE); Assert.assertNotNull(headers1); Assert.assertEquals(1, headers1.length); Assert.assertEquals("name1=value; name2=value; name3=value", headers1[0].getValue()); } @Test public void testAddSpecVersionHeader() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); this.cookieStore.clear(); final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value1"); cookie1.setVersion(0); cookie1.setDomain("localhost.local"); cookie1.setPath("/"); this.cookieStore.addCookie(cookie1); final BasicClientCookie cookie2 = new BasicClientCookie("name2", "value2"); cookie2.setVersion(0); cookie2.setDomain("localhost.local"); cookie2.setPath("/"); this.cookieStore.addCookie(cookie2); final HttpRoute route = new HttpRoute(this.target, null, false); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry); final HttpRequestInterceptor interceptor = new RequestAddCookies(); interceptor.process(request, context); final Header[] headers1 = request.getHeaders(SM.COOKIE); Assert.assertNotNull(headers1); Assert.assertEquals(1, headers1.length); Assert.assertEquals("name1=value1; name2=value2", headers1[0].getValue()); final Header[] headers2 = request.getHeaders(SM.COOKIE2); Assert.assertNotNull(headers2); Assert.assertEquals(1, headers2.length); Assert.assertEquals("$Version=1", headers2[0].getValue()); } } ././@LongLink0100644 0000000 0000000 00000000157 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestRequestAuthCache.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestRequestAuth0100644 0000000 0000000 00000026521 12301751654 032633 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.auth.AuthProtocolState; import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthState; import org.apache.http.auth.Credentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthCache; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.message.BasicHttpRequest; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestRequestAuthCache { private HttpHost target; private HttpHost proxy; private Credentials creds1; private Credentials creds2; private AuthScope authscope1; private AuthScope authscope2; private BasicScheme authscheme1; private BasicScheme authscheme2; private BasicCredentialsProvider credProvider; private AuthState targetState; private AuthState proxyState; @Before public void setUp() { this.target = new HttpHost("localhost", 80); this.proxy = new HttpHost("localhost", 8080); this.credProvider = new BasicCredentialsProvider(); this.creds1 = new UsernamePasswordCredentials("user1", "secret1"); this.creds2 = new UsernamePasswordCredentials("user2", "secret2"); this.authscope1 = new AuthScope(this.target); this.authscope2 = new AuthScope(this.proxy); this.authscheme1 = new BasicScheme(); this.authscheme2 = new BasicScheme(); this.credProvider.setCredentials(this.authscope1, this.creds1); this.credProvider.setCredentials(this.authscope2, this.creds2); this.targetState = new AuthState(); this.proxyState = new AuthState(); } @Test(expected=IllegalArgumentException.class) public void testRequestParameterCheck() throws Exception { final HttpClientContext context = HttpClientContext.create(); final HttpRequestInterceptor interceptor = new RequestAuthCache(); interceptor.process(null, context); } @Test(expected=IllegalArgumentException.class) public void testContextParameterCheck() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpRequestInterceptor interceptor = new RequestAuthCache(); interceptor.process(request, null); } @Test public void testPreemptiveTargetAndProxyAuth() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.CREDS_PROVIDER, this.credProvider); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, new HttpRoute(this.target, null, this.proxy, false)); context.setAttribute(HttpClientContext.TARGET_AUTH_STATE, this.targetState); context.setAttribute(HttpClientContext.PROXY_AUTH_STATE, this.proxyState); final AuthCache authCache = new BasicAuthCache(); authCache.put(this.target, this.authscheme1); authCache.put(this.proxy, this.authscheme2); context.setAttribute(HttpClientContext.AUTH_CACHE, authCache); final HttpRequestInterceptor interceptor = new RequestAuthCache(); interceptor.process(request, context); Assert.assertSame(this.authscheme1, this.targetState.getAuthScheme()); Assert.assertSame(this.creds1, this.targetState.getCredentials()); Assert.assertSame(this.authscheme2, this.proxyState.getAuthScheme()); Assert.assertSame(this.creds2, this.proxyState.getCredentials()); } @Test public void testCredentialsProviderNotSet() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.CREDS_PROVIDER, null); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, new HttpRoute(this.target, null, this.proxy, false)); context.setAttribute(HttpClientContext.TARGET_AUTH_STATE, this.targetState); context.setAttribute(HttpClientContext.PROXY_AUTH_STATE, this.proxyState); final AuthCache authCache = new BasicAuthCache(); authCache.put(this.target, this.authscheme1); authCache.put(this.proxy, this.authscheme2); context.setAttribute(HttpClientContext.AUTH_CACHE, authCache); final HttpRequestInterceptor interceptor = new RequestAuthCache(); interceptor.process(request, context); Assert.assertNull(this.targetState.getAuthScheme()); Assert.assertNull(this.targetState.getCredentials()); Assert.assertNull(this.proxyState.getAuthScheme()); Assert.assertNull(this.proxyState.getCredentials()); } @Test public void testAuthCacheNotSet() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.CREDS_PROVIDER, this.credProvider); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, new HttpRoute(this.target, null, this.proxy, false)); context.setAttribute(HttpClientContext.TARGET_AUTH_STATE, this.targetState); context.setAttribute(HttpClientContext.PROXY_AUTH_STATE, this.proxyState); context.setAttribute(HttpClientContext.AUTH_CACHE, null); final HttpRequestInterceptor interceptor = new RequestAuthCache(); interceptor.process(request, context); Assert.assertNull(this.targetState.getAuthScheme()); Assert.assertNull(this.targetState.getCredentials()); Assert.assertNull(this.proxyState.getAuthScheme()); Assert.assertNull(this.proxyState.getCredentials()); } @Test public void testAuthCacheEmpty() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.CREDS_PROVIDER, this.credProvider); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, new HttpRoute(this.target, null, this.proxy, false)); context.setAttribute(HttpClientContext.TARGET_AUTH_STATE, this.targetState); context.setAttribute(HttpClientContext.PROXY_AUTH_STATE, this.proxyState); final AuthCache authCache = new BasicAuthCache(); context.setAttribute(HttpClientContext.AUTH_CACHE, authCache); final HttpRequestInterceptor interceptor = new RequestAuthCache(); interceptor.process(request, context); Assert.assertNull(this.targetState.getAuthScheme()); Assert.assertNull(this.targetState.getCredentials()); Assert.assertNull(this.proxyState.getAuthScheme()); Assert.assertNull(this.proxyState.getCredentials()); } @Test public void testNoMatchingCredentials() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); this.credProvider.clear(); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.CREDS_PROVIDER, this.credProvider); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, new HttpRoute(this.target, null, this.proxy, false)); context.setAttribute(HttpClientContext.TARGET_AUTH_STATE, this.targetState); context.setAttribute(HttpClientContext.PROXY_AUTH_STATE, this.proxyState); final AuthCache authCache = new BasicAuthCache(); authCache.put(this.target, this.authscheme1); authCache.put(this.proxy, this.authscheme2); context.setAttribute(HttpClientContext.AUTH_CACHE, authCache); final HttpRequestInterceptor interceptor = new RequestAuthCache(); interceptor.process(request, context); Assert.assertNull(this.targetState.getAuthScheme()); Assert.assertNull(this.targetState.getCredentials()); Assert.assertNull(this.proxyState.getAuthScheme()); Assert.assertNull(this.proxyState.getCredentials()); } @Test public void testAuthSchemeAlreadySet() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.CREDS_PROVIDER, this.credProvider); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, this.target); context.setAttribute(HttpClientContext.HTTP_ROUTE, new HttpRoute(this.target, null, this.proxy, false)); context.setAttribute(HttpClientContext.TARGET_AUTH_STATE, this.targetState); context.setAttribute(HttpClientContext.PROXY_AUTH_STATE, this.proxyState); final AuthCache authCache = new BasicAuthCache(); authCache.put(this.target, this.authscheme1); authCache.put(this.proxy, this.authscheme2); context.setAttribute(HttpClientContext.AUTH_CACHE, authCache); this.targetState.setState(AuthProtocolState.CHALLENGED); this.targetState.update(new BasicScheme(), new UsernamePasswordCredentials("user3", "secret3")); this.proxyState.setState(AuthProtocolState.CHALLENGED); this.proxyState.update(new BasicScheme(), new UsernamePasswordCredentials("user4", "secret4")); final HttpRequestInterceptor interceptor = new RequestAuthCache(); interceptor.process(request, context); Assert.assertNotSame(this.authscheme1, this.targetState.getAuthScheme()); Assert.assertNotSame(this.creds1, this.targetState.getCredentials()); Assert.assertNotSame(this.authscheme2, this.proxyState.getAuthScheme()); Assert.assertNotSame(this.creds2, this.proxyState.getCredentials()); } } ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestRequestClientConnControl.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestRequestClie0100644 0000000 0000000 00000016650 12301751654 032610 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.RouteInfo.LayerType; import org.apache.http.conn.routing.RouteInfo.TunnelType; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.HTTP; import org.junit.Assert; import org.junit.Test; public class TestRequestClientConnControl { @Test(expected=IllegalArgumentException.class) public void testRequestParameterCheck() throws Exception { final HttpClientContext context = HttpClientContext.create(); final HttpRequestInterceptor interceptor = new RequestClientConnControl(); interceptor.process(null, context); } @Test public void testConnectionKeepAliveForConnectRequest() throws Exception { final HttpRequest request = new BasicHttpRequest("CONNECT", "www.somedomain.com"); final HttpClientContext context = HttpClientContext.create(); final HttpRequestInterceptor interceptor = new RequestClientConnControl(); interceptor.process(request, context); final Header header1 = request.getFirstHeader("Proxy-Connection"); Assert.assertNotNull(header1); Assert.assertEquals(HTTP.CONN_KEEP_ALIVE, header1.getValue()); final Header header2 = request.getFirstHeader(HTTP.CONN_DIRECTIVE); Assert.assertNull(header2); } @Test public void testConnectionKeepAliveForDirectRequests() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpClientContext context = HttpClientContext.create(); final HttpHost target = new HttpHost("localhost", 80, "http"); final HttpRoute route = new HttpRoute(target, null, false); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); final HttpRequestInterceptor interceptor = new RequestClientConnControl(); interceptor.process(request, context); final Header header1 = request.getFirstHeader(HTTP.CONN_DIRECTIVE); Assert.assertNotNull(header1); Assert.assertEquals(HTTP.CONN_KEEP_ALIVE, header1.getValue()); final Header header2 = request.getFirstHeader("Proxy-Connection"); Assert.assertNull(header2); } @Test public void testConnectionKeepAliveForTunneledRequests() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpClientContext context = HttpClientContext.create(); final HttpHost target = new HttpHost("localhost", 443, "https"); final HttpHost proxy = new HttpHost("localhost", 8080); final HttpRoute route = new HttpRoute(target, null, proxy, true, TunnelType.TUNNELLED, LayerType.LAYERED); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); final HttpRequestInterceptor interceptor = new RequestClientConnControl(); interceptor.process(request, context); final Header header1 = request.getFirstHeader(HTTP.CONN_DIRECTIVE); Assert.assertNotNull(header1); Assert.assertEquals(HTTP.CONN_KEEP_ALIVE, header1.getValue()); final Header header2 = request.getFirstHeader("Proxy-Connection"); Assert.assertNull(header2); } @Test public void testProxyConnectionKeepAliveForRequestsOverProxy() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpClientContext context = HttpClientContext.create(); final HttpHost target = new HttpHost("localhost", 80, "http"); final HttpHost proxy = new HttpHost("localhost", 8080); final HttpRoute route = new HttpRoute(target, null, proxy, false, TunnelType.PLAIN, LayerType.PLAIN); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); final HttpRequestInterceptor interceptor = new RequestClientConnControl(); interceptor.process(request, context); final Header header1 = request.getFirstHeader("Proxy-Connection"); Assert.assertNotNull(header1); Assert.assertEquals(HTTP.CONN_KEEP_ALIVE, header1.getValue()); final Header header2 = request.getFirstHeader(HTTP.CONN_DIRECTIVE); Assert.assertNull(header2); } @Test public void testPreserveCustomConnectionHeader() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); request.addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); final HttpClientContext context = HttpClientContext.create(); final HttpHost target = new HttpHost("localhost", 443, "https"); final HttpHost proxy = new HttpHost("localhost", 8080); final HttpRoute route = new HttpRoute(target, null, proxy, true, TunnelType.TUNNELLED, LayerType.LAYERED); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); final HttpRequestInterceptor interceptor = new RequestClientConnControl(); interceptor.process(request, context); final Header header1 = request.getFirstHeader(HTTP.CONN_DIRECTIVE); Assert.assertNotNull(header1); Assert.assertEquals(HTTP.CONN_CLOSE, header1.getValue()); final Header header2 = request.getFirstHeader("Proxy-Connection"); Assert.assertNull(header2); } @Test public void testPreserveCustomProxyConnectionHeader() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); request.addHeader("Proxy-Connection", HTTP.CONN_CLOSE); final HttpClientContext context = HttpClientContext.create(); final HttpHost target = new HttpHost("localhost", 80, "http"); final HttpHost proxy = new HttpHost("localhost", 8080); final HttpRoute route = new HttpRoute(target, null, proxy, false, TunnelType.PLAIN, LayerType.PLAIN); context.setAttribute(HttpClientContext.HTTP_ROUTE, route); final HttpRequestInterceptor interceptor = new RequestClientConnControl(); interceptor.process(request, context); final Header header1 = request.getFirstHeader("Proxy-Connection"); Assert.assertNotNull(header1); Assert.assertEquals(HTTP.CONN_CLOSE, header1.getValue()); } } ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestRequestDefaultHeaders.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestRequestDefa0100644 0000000 0000000 00000006463 12301751654 032574 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.util.ArrayList; import java.util.List; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.junit.Assert; import org.junit.Test; public class TestRequestDefaultHeaders { @Test(expected=IllegalArgumentException.class) public void testRequestParameterCheck() throws Exception { final HttpContext context = new BasicHttpContext(); final HttpRequestInterceptor interceptor = new RequestDefaultHeaders(); interceptor.process(null, context); } @Test public void testNoDefaultHeadersForConnectRequest() throws Exception { final HttpRequest request = new BasicHttpRequest("CONNECT", "www.somedomain.com"); final List

defheaders = new ArrayList
(); defheaders.add(new BasicHeader("custom", "stuff")); final HttpContext context = new BasicHttpContext(); final HttpRequestInterceptor interceptor = new RequestDefaultHeaders(defheaders); interceptor.process(request, context); final Header header1 = request.getFirstHeader("custom"); Assert.assertNull(header1); } @Test public void testDefaultHeaders() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); request.addHeader("custom", "stuff"); final List
defheaders = new ArrayList
(); defheaders.add(new BasicHeader("custom", "more stuff")); final HttpContext context = new BasicHttpContext(); final HttpRequestInterceptor interceptor = new RequestDefaultHeaders(defheaders); interceptor.process(request, context); final Header[] headers = request.getHeaders("custom"); Assert.assertNotNull(headers); Assert.assertEquals(2, headers.length); Assert.assertEquals("stuff", headers[0].getValue()); Assert.assertEquals("more stuff", headers[1].getValue()); } } ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestRequestExpectContinue.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestRequestExpe0100644 0000000 0000000 00000013431 12301751654 032627 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import org.apache.http.Header; import org.apache.http.HttpVersion; import org.apache.http.client.config.RequestConfig; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicHttpEntityEnclosingRequest; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.junit.Assert; import org.junit.Test; public class TestRequestExpectContinue { @Test public void testRequestExpectContinueGenerated() throws Exception { final HttpClientContext context = HttpClientContext.create(); final RequestConfig config = RequestConfig.custom().setExpectContinueEnabled(true).build(); context.setAttribute(HttpClientContext.REQUEST_CONFIG, config); final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/"); final String s = "whatever"; final StringEntity entity = new StringEntity(s, "US-ASCII"); request.setEntity(entity); final RequestExpectContinue interceptor = new RequestExpectContinue(); interceptor.process(request, context); final Header header = request.getFirstHeader(HTTP.EXPECT_DIRECTIVE); Assert.assertNotNull(header); Assert.assertEquals(HTTP.EXPECT_CONTINUE, header.getValue()); } @Test public void testRequestExpectContinueNotGenerated() throws Exception { final HttpContext context = new BasicHttpContext(null); final RequestConfig config = RequestConfig.custom().setExpectContinueEnabled(false).build(); context.setAttribute(HttpClientContext.REQUEST_CONFIG, config); final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/"); final String s = "whatever"; final StringEntity entity = new StringEntity(s, "US-ASCII"); request.setEntity(entity); final RequestExpectContinue interceptor = new RequestExpectContinue(); interceptor.process(request, context); final Header header = request.getFirstHeader(HTTP.EXPECT_DIRECTIVE); Assert.assertNull(header); } @Test public void testRequestExpectContinueHTTP10() throws Exception { final HttpContext context = new BasicHttpContext(null); final RequestConfig config = RequestConfig.custom().setExpectContinueEnabled(true).build(); context.setAttribute(HttpClientContext.REQUEST_CONFIG, config); final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest( "POST", "/", HttpVersion.HTTP_1_0); final String s = "whatever"; final StringEntity entity = new StringEntity(s, "US-ASCII"); request.setEntity(entity); final RequestExpectContinue interceptor = new RequestExpectContinue(); interceptor.process(request, context); final Header header = request.getFirstHeader(HTTP.EXPECT_DIRECTIVE); Assert.assertNull(header); } @Test public void testRequestExpectContinueZeroContent() throws Exception { final HttpContext context = new BasicHttpContext(null); final RequestConfig config = RequestConfig.custom().setExpectContinueEnabled(true).build(); context.setAttribute(HttpClientContext.REQUEST_CONFIG, config); final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/"); final String s = ""; final StringEntity entity = new StringEntity(s, "US-ASCII"); request.setEntity(entity); final RequestExpectContinue interceptor = new RequestExpectContinue(); interceptor.process(request, context); final Header header = request.getFirstHeader(HTTP.EXPECT_DIRECTIVE); Assert.assertNull(header); } @Test public void testRequestExpectContinueInvalidInput() throws Exception { final RequestExpectContinue interceptor = new RequestExpectContinue(); try { interceptor.process(null, null); Assert.fail("IllegalArgumentException should have been thrown"); } catch (final IllegalArgumentException ex) { // expected } } @Test public void testRequestExpectContinueIgnoreNonenclosingRequests() throws Exception { final HttpContext context = new BasicHttpContext(null); final BasicHttpRequest request = new BasicHttpRequest("POST", "/"); final RequestExpectContinue interceptor = new RequestExpectContinue(); interceptor.process(request, context); Assert.assertEquals(0, request.getAllHeaders().length); } } ././@LongLink0100644 0000000 0000000 00000000166 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestResponseContentEncoding.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestResponseCon0100644 0000000 0000000 00000015346 12301751654 032622 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseInterceptor; import org.apache.http.HttpVersion; import org.apache.http.client.entity.DeflateDecompressingEntity; import org.apache.http.client.entity.GzipDecompressingEntity; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicHttpResponse; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.junit.Assert; import org.junit.Test; public class TestResponseContentEncoding { @Test public void testContentEncodingNoEntity() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); final HttpContext context = new BasicHttpContext(); final HttpResponseInterceptor interceptor = new ResponseContentEncoding(); interceptor.process(response, context); final HttpEntity entity = response.getEntity(); Assert.assertNull(entity); } @Test public void testNoContentEncoding() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); final StringEntity original = new StringEntity("plain stuff"); response.setEntity(original); final HttpContext context = new BasicHttpContext(); final HttpResponseInterceptor interceptor = new ResponseContentEncoding(); interceptor.process(response, context); final HttpEntity entity = response.getEntity(); Assert.assertNotNull(entity); Assert.assertTrue(entity instanceof StringEntity); } @Test public void testGzipContentEncoding() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); final StringEntity original = new StringEntity("encoded stuff"); original.setContentEncoding("GZip"); response.setEntity(original); final HttpContext context = new BasicHttpContext(); final HttpResponseInterceptor interceptor = new ResponseContentEncoding(); interceptor.process(response, context); final HttpEntity entity = response.getEntity(); Assert.assertNotNull(entity); Assert.assertTrue(entity instanceof GzipDecompressingEntity); } @Test public void testGzipContentEncodingZeroLength() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); final StringEntity original = new StringEntity(""); original.setContentEncoding("GZip"); response.setEntity(original); final HttpContext context = new BasicHttpContext(); final HttpResponseInterceptor interceptor = new ResponseContentEncoding(); interceptor.process(response, context); final HttpEntity entity = response.getEntity(); Assert.assertNotNull(entity); Assert.assertTrue(entity instanceof StringEntity); } @Test public void testXGzipContentEncoding() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); final StringEntity original = new StringEntity("encoded stuff"); original.setContentEncoding("x-gzip"); response.setEntity(original); final HttpContext context = new BasicHttpContext(); final HttpResponseInterceptor interceptor = new ResponseContentEncoding(); interceptor.process(response, context); final HttpEntity entity = response.getEntity(); Assert.assertNotNull(entity); Assert.assertTrue(entity instanceof GzipDecompressingEntity); } @Test public void testDeflateContentEncoding() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); final StringEntity original = new StringEntity("encoded stuff"); original.setContentEncoding("deFlaTe"); response.setEntity(original); final HttpContext context = new BasicHttpContext(); final HttpResponseInterceptor interceptor = new ResponseContentEncoding(); interceptor.process(response, context); final HttpEntity entity = response.getEntity(); Assert.assertNotNull(entity); Assert.assertTrue(entity instanceof DeflateDecompressingEntity); } @Test public void testIdentityContentEncoding() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); final StringEntity original = new StringEntity("encoded stuff"); original.setContentEncoding("identity"); response.setEntity(original); final HttpContext context = new BasicHttpContext(); final HttpResponseInterceptor interceptor = new ResponseContentEncoding(); interceptor.process(response, context); final HttpEntity entity = response.getEntity(); Assert.assertNotNull(entity); Assert.assertTrue(entity instanceof StringEntity); } @Test(expected=HttpException.class) public void testUnknownContentEncoding() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); final StringEntity original = new StringEntity("encoded stuff"); original.setContentEncoding("whatever"); response.setEntity(original); final HttpContext context = new BasicHttpContext(); final HttpResponseInterceptor interceptor = new ResponseContentEncoding(); interceptor.process(response, context); } } ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestResponseProcessCookies.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/protocol/TestResponsePro0100644 0000000 0000000 00000022227 12301751654 032637 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.protocol; import java.util.List; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseInterceptor; import org.apache.http.HttpVersion; import org.apache.http.client.CookieStore; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.SM; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.cookie.BestMatchSpec; import org.apache.http.message.BasicHttpResponse; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestResponseProcessCookies { private CookieOrigin cookieOrigin; private CookieSpec cookieSpec; private CookieStore cookieStore; @Before public void setUp() throws Exception { this.cookieOrigin = new CookieOrigin("localhost", 80, "/", false); this.cookieSpec = new BestMatchSpec(); this.cookieStore = new BasicCookieStore(); } @Test(expected=IllegalArgumentException.class) public void testResponseParameterCheck() throws Exception { final HttpClientContext context = HttpClientContext.create(); final HttpResponseInterceptor interceptor = new ResponseProcessCookies(); interceptor.process(null, context); } @Test(expected=IllegalArgumentException.class) public void testContextParameterCheck() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); final HttpResponseInterceptor interceptor = new ResponseProcessCookies(); interceptor.process(response, null); } @Test public void testParseCookies() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); response.addHeader(SM.SET_COOKIE, "name1=value1"); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.COOKIE_ORIGIN, this.cookieOrigin); context.setAttribute(HttpClientContext.COOKIE_SPEC, this.cookieSpec); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); final HttpResponseInterceptor interceptor = new ResponseProcessCookies(); interceptor.process(response, context); final List cookies = this.cookieStore.getCookies(); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final Cookie cookie = cookies.get(0); Assert.assertEquals(0, cookie.getVersion()); Assert.assertEquals("name1", cookie.getName()); Assert.assertEquals("value1", cookie.getValue()); Assert.assertEquals("localhost", cookie.getDomain()); Assert.assertEquals("/", cookie.getPath()); } @Test public void testNoCookieOrigin() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); response.addHeader(SM.SET_COOKIE, "name1=value1"); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.COOKIE_ORIGIN, null); context.setAttribute(HttpClientContext.COOKIE_SPEC, this.cookieSpec); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); final HttpResponseInterceptor interceptor = new ResponseProcessCookies(); interceptor.process(response, context); final List cookies = this.cookieStore.getCookies(); Assert.assertNotNull(cookies); Assert.assertEquals(0, cookies.size()); } @Test public void testNoCookieSpec() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); response.addHeader(SM.SET_COOKIE, "name1=value1"); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.COOKIE_ORIGIN, this.cookieOrigin); context.setAttribute(HttpClientContext.COOKIE_SPEC, null); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); final HttpResponseInterceptor interceptor = new ResponseProcessCookies(); interceptor.process(response, context); final List cookies = this.cookieStore.getCookies(); Assert.assertNotNull(cookies); Assert.assertEquals(0, cookies.size()); } @Test public void testNoCookieStore() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); response.addHeader(SM.SET_COOKIE, "name1=value1"); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.COOKIE_ORIGIN, this.cookieOrigin); context.setAttribute(HttpClientContext.COOKIE_SPEC, this.cookieSpec); context.setAttribute(HttpClientContext.COOKIE_STORE, null); final HttpResponseInterceptor interceptor = new ResponseProcessCookies(); interceptor.process(response, context); final List cookies = this.cookieStore.getCookies(); Assert.assertNotNull(cookies); Assert.assertEquals(0, cookies.size()); } @Test public void testSetCookie2OverrideSetCookie() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); response.addHeader(SM.SET_COOKIE, "name1=value1"); response.addHeader(SM.SET_COOKIE2, "name1=value2; Version=1"); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.COOKIE_ORIGIN, this.cookieOrigin); context.setAttribute(HttpClientContext.COOKIE_SPEC, this.cookieSpec); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); final HttpResponseInterceptor interceptor = new ResponseProcessCookies(); interceptor.process(response, context); final List cookies = this.cookieStore.getCookies(); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final Cookie cookie = cookies.get(0); Assert.assertEquals(1, cookie.getVersion()); Assert.assertEquals("name1", cookie.getName()); Assert.assertEquals("value2", cookie.getValue()); Assert.assertEquals("localhost.local", cookie.getDomain()); Assert.assertEquals("/", cookie.getPath()); } @Test public void testInvalidHeader() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); response.addHeader(SM.SET_COOKIE2, "name=value; Version=crap"); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.COOKIE_ORIGIN, this.cookieOrigin); context.setAttribute(HttpClientContext.COOKIE_SPEC, this.cookieSpec); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); final HttpResponseInterceptor interceptor = new ResponseProcessCookies(); interceptor.process(response, context); final List cookies = this.cookieStore.getCookies(); Assert.assertNotNull(cookies); Assert.assertTrue(cookies.isEmpty()); } @Test public void testCookieRejected() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); response.addHeader(SM.SET_COOKIE2, "name=value; Domain=www.somedomain.com; Version=1"); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpClientContext.COOKIE_ORIGIN, this.cookieOrigin); context.setAttribute(HttpClientContext.COOKIE_SPEC, this.cookieSpec); context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore); final HttpResponseInterceptor interceptor = new ResponseProcessCookies(); interceptor.process(response, context); final List cookies = this.cookieStore.getCookies(); Assert.assertNotNull(cookies); Assert.assertTrue(cookies.isEmpty()); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/utils/0040755 0000000 0000000 00000000000 12301751654 027072 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000145 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/utils/TestDateUtils.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/utils/TestDateUtils.java0100644 0000000 0000000 00000012456 12301751654 032500 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import java.util.Calendar; import java.util.Date; import org.apache.http.impl.cookie.DateParseException; import org.junit.Assert; import org.junit.Test; /** * Unit tests for {@link DateUtils}. */ public class TestDateUtils { @Test public void testBasicDateParse() throws Exception { final Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(DateUtils.GMT); calendar.set(2005, Calendar.OCTOBER, 14, 0, 0, 0); calendar.set(Calendar.MILLISECOND, 0); final Date date1 = calendar.getTime(); final String[] formats = new String[] { DateUtils.PATTERN_RFC1123 }; Date date2 = DateUtils.parseDate("Fri, 14 Oct 2005 00:00:00 GMT", formats, null); Assert.assertEquals(date1, date2); date2 = DateUtils.parseDate("Fri, 14 Oct 2005 00:00:00 GMT", formats); Assert.assertEquals(date1, date2); date2 = DateUtils.parseDate("Fri, 14 Oct 2005 00:00:00 GMT"); Assert.assertEquals(date1, date2); } @Test public void testMalformedDate() { Assert.assertNull(DateUtils.parseDate("Fri, 14 Oct 2005 00:00:00 GMT", new String[] {}, null)); } @Test public void testInvalidInput() throws Exception { try { DateUtils.parseDate(null, null, null); Assert.fail("IllegalArgumentException should habe been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { DateUtils.formatDate(null); Assert.fail("IllegalArgumentException should habe been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { DateUtils.formatDate(new Date(), null); Assert.fail("IllegalArgumentException should habe been thrown"); } catch (final IllegalArgumentException ex) { // expected } } @Test public void testTwoDigitYearDateParse() throws Exception { final Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(DateUtils.GMT); calendar.set(2005, Calendar.OCTOBER, 14, 0, 0, 0); calendar.set(Calendar.MILLISECOND, 0); Date date1 = calendar.getTime(); final String[] formats = new String[] { DateUtils.PATTERN_RFC1036 }; Date date2 = DateUtils.parseDate("Friday, 14-Oct-05 00:00:00 GMT", formats, null); Assert.assertEquals(date1, date2); calendar.set(1900, Calendar.JANUARY, 0, 0, 0, 0); calendar.set(Calendar.MILLISECOND, 0); final Date startDate = calendar.getTime(); calendar.set(1905, Calendar.OCTOBER, 14, 0, 0, 0); calendar.set(Calendar.MILLISECOND, 0); date1 = calendar.getTime(); date2 = DateUtils.parseDate("Friday, 14-Oct-05 00:00:00 GMT", formats, startDate); Assert.assertEquals(date1, date2); } @Test public void testParseQuotedDate() throws Exception { final Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(DateUtils.GMT); calendar.set(2005, Calendar.OCTOBER, 14, 0, 0, 0); calendar.set(Calendar.MILLISECOND, 0); final Date date1 = calendar.getTime(); final String[] formats = new String[] { DateUtils.PATTERN_RFC1123 }; final Date date2 = DateUtils.parseDate("'Fri, 14 Oct 2005 00:00:00 GMT'", formats); Assert.assertEquals(date1, date2); } @Test public void testBasicDateFormat() throws Exception { final Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(DateUtils.GMT); calendar.set(2005, Calendar.OCTOBER, 14, 0, 0, 0); calendar.set(Calendar.MILLISECOND, 0); final Date date = calendar.getTime(); Assert.assertEquals("Fri, 14 Oct 2005 00:00:00 GMT", DateUtils.formatDate(date)); Assert.assertEquals("Fri, 14 Oct 2005 00:00:00 GMT", DateUtils.formatDate(date, DateUtils.PATTERN_RFC1123)); } @Test public void testConstructor() { new DateParseException(); new DateParseException("Oppsie"); } } ././@LongLink0100644 0000000 0000000 00000000153 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/utils/TestHttpClientUtils.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/utils/TestHttpClientUtil0100644 0000000 0000000 00000014746 12301751654 032602 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import java.io.IOException; import java.io.InputStream; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.impl.client.CloseableHttpClient; import org.junit.Test; import org.mockito.Mockito; public class TestHttpClientUtils { @Test public void testCloseQuietlyResponseNull() throws Exception { final HttpResponse response = null; HttpClientUtils.closeQuietly(response); } @Test public void testCloseQuietlyResponseEntityNull() throws Exception { final HttpResponse response = Mockito.mock(HttpResponse.class); HttpClientUtils.closeQuietly(response); Mockito.verify(response).getEntity(); } @Test public void testCloseQuietlyResponseEntityNonStreaming() throws Exception { final HttpResponse response = Mockito.mock(HttpResponse.class); final HttpEntity entity = Mockito.mock(HttpEntity.class); Mockito.when(response.getEntity()).thenReturn(entity); Mockito.when(entity.isStreaming()).thenReturn(Boolean.FALSE); HttpClientUtils.closeQuietly(response); Mockito.verify(entity, Mockito.never()).getContent(); } @Test public void testCloseQuietlyResponseEntity() throws Exception { final HttpResponse response = Mockito.mock(HttpResponse.class); final HttpEntity entity = Mockito.mock(HttpEntity.class); final InputStream instream = Mockito.mock(InputStream.class); Mockito.when(response.getEntity()).thenReturn(entity); Mockito.when(entity.isStreaming()).thenReturn(Boolean.TRUE); Mockito.when(entity.getContent()).thenReturn(instream); HttpClientUtils.closeQuietly(response); Mockito.verify(instream).close(); } @Test public void testCloseQuietlyResponseIgnoreIOError() throws Exception { final HttpResponse response = Mockito.mock(HttpResponse.class); final HttpEntity entity = Mockito.mock(HttpEntity.class); final InputStream instream = Mockito.mock(InputStream.class); Mockito.when(response.getEntity()).thenReturn(entity); Mockito.when(entity.getContent()).thenReturn(instream); Mockito.doThrow(new IOException()).when(instream).close(); HttpClientUtils.closeQuietly(response); } @Test public void testCloseQuietlyCloseableResponseNull() throws Exception { final CloseableHttpResponse response = null; HttpClientUtils.closeQuietly(response); } @Test public void testCloseQuietlyCloseableResponseEntityNull() throws Exception { final CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class); HttpClientUtils.closeQuietly(response); Mockito.verify(response).getEntity(); Mockito.verify(response).close(); } @Test public void testCloseQuietlyCloseableResponseEntityNonStreaming() throws Exception { final CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class); final HttpEntity entity = Mockito.mock(HttpEntity.class); Mockito.when(response.getEntity()).thenReturn(entity); Mockito.when(entity.isStreaming()).thenReturn(Boolean.FALSE); HttpClientUtils.closeQuietly(response); Mockito.verify(entity, Mockito.never()).getContent(); Mockito.verify(response).close(); } @Test public void testCloseQuietlyCloseableResponseEntity() throws Exception { final CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class); final HttpEntity entity = Mockito.mock(HttpEntity.class); final InputStream instream = Mockito.mock(InputStream.class); Mockito.when(response.getEntity()).thenReturn(entity); Mockito.when(entity.isStreaming()).thenReturn(Boolean.TRUE); Mockito.when(entity.getContent()).thenReturn(instream); HttpClientUtils.closeQuietly(response); Mockito.verify(instream).close(); Mockito.verify(response).close(); } @Test public void testCloseQuietlyCloseableResponseIgnoreIOError() throws Exception { final CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class); final HttpEntity entity = Mockito.mock(HttpEntity.class); final InputStream instream = Mockito.mock(InputStream.class); Mockito.when(response.getEntity()).thenReturn(entity); Mockito.when(entity.getContent()).thenReturn(instream); Mockito.doThrow(new IOException()).when(instream).close(); HttpClientUtils.closeQuietly(response); } @Test public void testCloseQuietlyHttpClientNull() throws Exception { final CloseableHttpClient httpclient = null; HttpClientUtils.closeQuietly(httpclient); } @Test public void testCloseQuietlyHttpClient() throws Exception { final CloseableHttpClient httpclient = Mockito.mock(CloseableHttpClient.class); HttpClientUtils.closeQuietly(httpclient); Mockito.verify(httpclient).close(); } @Test public void testCloseQuietlyCloseableHttpClientIgnoreIOError() throws Exception { final CloseableHttpClient httpclient = Mockito.mock(CloseableHttpClient.class); Mockito.doThrow(new IOException()).when(httpclient).close(); HttpClientUtils.closeQuietly(httpclient); } } ././@LongLink0100644 0000000 0000000 00000000146 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/utils/TestRfc3492Idn.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/utils/TestRfc3492Idn.jav0100644 0000000 0000000 00000006156 12301751654 032130 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import org.junit.Assert; import org.junit.Test; public class TestRfc3492Idn { /** * Some of the sample strings from RFC 3492 */ @Test public void testDecode() throws Exception { final Rfc3492Idn idn = new Rfc3492Idn(); // (A) Arabic Assert.assertEquals("\u0644\u064A\u0647\u0645\u0627\u0628\u062A\u0643\u0644" + "\u0645\u0648\u0634\u0639\u0631\u0628\u064A\u061F", idn.decode("egbpdaj6bu4bxfgehfvwxn")); // (B) Chinese (simplified) Assert.assertEquals("\u4ED6\u4EEC\u4E3A\u4EC0\u4E48\u4E0D\u8BF4\u4E2D\u6587", idn.decode("ihqwcrb4cv8a8dqg056pqjye")); // (I) Russian (Cyrillic) Assert.assertEquals("\u043F\u043E\u0447\u0435\u043C\u0443\u0436\u0435\u043E"+ "\u043D\u0438\u043D\u0435\u0433\u043E\u0432\u043E\u0440"+ "\u044F\u0442\u043F\u043E\u0440\u0443\u0441\u0441\u043A"+ "\u0438", idn.decode("b1abfaaepdrnnbgefbaDotcwatmq2g4l")); // (P) MajiKoi5 Assert.assertEquals("\u004D\u0061\u006A\u0069\u3067\u004B\u006F\u0069\u3059" + "\u308B\u0035\u79D2\u524D", idn.decode("MajiKoi5-783gue6qz075azm5e")); } @Test public void testToUnicode() throws Exception { final Rfc3492Idn idn = new Rfc3492Idn(); // (A) Arabic Assert.assertEquals("\u0644\u064A\u0647\u0645\u0627\u0628\u062A\u0643\u0644" + "\u0645\u0648\u0634\u0639\u0631\u0628\u064A\u061F", idn.toUnicode("xn--egbpdaj6bu4bxfgehfvwxn")); // some real-world domains Assert.assertEquals("www.z\u00fcrich.ch", idn.toUnicode("www.xn--zrich-kva.ch")); Assert.assertEquals("www.g\u00e4ggelig\u00e4\u00e4l.ch", idn.toUnicode("www.xn--gggeligl-0zaga.ch")); } } ././@LongLink0100644 0000000 0000000 00000000146 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/utils/TestURIBuilder.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/utils/TestURIBuilder.jav0100644 0000000 0000000 00000023303 12301751654 032400 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import java.net.URI; import org.junit.Assert; import org.junit.Test; public class TestURIBuilder { @Test public void testHierarchicalUri() throws Exception { final URI uri = new URI("http", "stuff", "localhost", 80, "/some stuff", "param=stuff", "fragment"); final URIBuilder uribuilder = new URIBuilder(uri); final URI result = uribuilder.build(); Assert.assertEquals(new URI("http://stuff@localhost:80/some%20stuff?param=stuff#fragment"), result); } @Test public void testMutationToRelativeUri() throws Exception { final URI uri = new URI("http://stuff@localhost:80/stuff?param=stuff#fragment"); final URIBuilder uribuilder = new URIBuilder(uri).setHost(null); final URI result = uribuilder.build(); Assert.assertEquals(new URI("http:///stuff?param=stuff#fragment"), result); } @Test public void testMutationRemoveFragment() throws Exception { final URI uri = new URI("http://stuff@localhost:80/stuff?param=stuff#fragment"); final URI result = new URIBuilder(uri).setFragment(null).build(); Assert.assertEquals(new URI("http://stuff@localhost:80/stuff?param=stuff"), result); } @Test public void testMutationRemoveUserInfo() throws Exception { final URI uri = new URI("http://stuff@localhost:80/stuff?param=stuff#fragment"); final URI result = new URIBuilder(uri).setUserInfo(null).build(); Assert.assertEquals(new URI("http://localhost:80/stuff?param=stuff#fragment"), result); } @Test public void testMutationRemovePort() throws Exception { final URI uri = new URI("http://stuff@localhost:80/stuff?param=stuff#fragment"); final URI result = new URIBuilder(uri).setPort(-1).build(); Assert.assertEquals(new URI("http://stuff@localhost/stuff?param=stuff#fragment"), result); } @Test public void testOpaqueUri() throws Exception { final URI uri = new URI("stuff", "some-stuff", "fragment"); final URIBuilder uribuilder = new URIBuilder(uri); final URI result = uribuilder.build(); Assert.assertEquals(uri, result); } @Test public void testOpaqueUriMutation() throws Exception { final URI uri = new URI("stuff", "some-stuff", "fragment"); final URIBuilder uribuilder = new URIBuilder(uri).setCustomQuery("param1¶m2=stuff").setFragment(null); Assert.assertEquals(new URI("stuff:?param1¶m2=stuff"), uribuilder.build()); } @Test public void testHierarchicalUriMutation() throws Exception { final URIBuilder uribuilder = new URIBuilder("/").setScheme("http").setHost("localhost").setPort(80).setPath("/stuff"); Assert.assertEquals(new URI("http://localhost:80/stuff"), uribuilder.build()); } @Test public void testEmpty() throws Exception { final URIBuilder uribuilder = new URIBuilder(); final URI result = uribuilder.build(); Assert.assertEquals(new URI(""), result); } @Test public void testSetUserInfo() throws Exception { final URI uri = new URI("http", null, "localhost", 80, "/", "param=stuff", null); final URIBuilder uribuilder = new URIBuilder(uri).setUserInfo("user", "password"); final URI result = uribuilder.build(); Assert.assertEquals(new URI("http://user:password@localhost:80/?param=stuff"), result); } @Test public void testRemoveParameters() throws Exception { final URI uri = new URI("http", null, "localhost", 80, "/", "param=stuff", null); final URIBuilder uribuilder = new URIBuilder(uri).removeQuery(); final URI result = uribuilder.build(); Assert.assertEquals(new URI("http://localhost:80/"), result); } @Test public void testSetParameter() throws Exception { final URI uri = new URI("http", null, "localhost", 80, "/", "param=stuff&blah&blah", null); final URIBuilder uribuilder = new URIBuilder(uri).setParameter("param", "some other stuff") .setParameter("blah", "blah"); final URI result = uribuilder.build(); Assert.assertEquals(new URI("http://localhost:80/?param=some+other+stuff&blah=blah"), result); } @Test public void testParameterWithSpecialChar() throws Exception { final URI uri = new URI("http", null, "localhost", 80, "/", "param=stuff", null); final URIBuilder uribuilder = new URIBuilder(uri).addParameter("param", "1 + 1 = 2") .addParameter("param", "blah&blah"); final URI result = uribuilder.build(); Assert.assertEquals(new URI("http://localhost:80/?param=stuff¶m=1+%2B+1+%3D+2&" + "param=blah%26blah"), result); } @Test public void testAddParameter() throws Exception { final URI uri = new URI("http", null, "localhost", 80, "/", "param=stuff&blah&blah", null); final URIBuilder uribuilder = new URIBuilder(uri).addParameter("param", "some other stuff") .addParameter("blah", "blah"); final URI result = uribuilder.build(); Assert.assertEquals(new URI("http://localhost:80/?param=stuff&blah&blah&" + "param=some+other+stuff&blah=blah"), result); } @Test public void testQueryEncoding() throws Exception { final URI uri1 = new URI("https://somehost.com/stuff?client_id=1234567890" + "&redirect_uri=https%3A%2F%2Fsomehost.com%2Fblah+blah%2F"); final URI uri2 = new URIBuilder("https://somehost.com/stuff") .addParameter("client_id","1234567890") .addParameter("redirect_uri","https://somehost.com/blah blah/").build(); Assert.assertEquals(uri1, uri2); } @Test public void testQueryAndParameterEncoding() throws Exception { final URI uri1 = new URI("https://somehost.com/stuff?param1=12345¶m2=67890"); final URI uri2 = new URIBuilder("https://somehost.com/stuff") .setCustomQuery("this&that") .addParameter("param1","12345") .addParameter("param2","67890").build(); Assert.assertEquals(uri1, uri2); } @Test public void testPathEncoding() throws Exception { final URI uri1 = new URI("https://somehost.com/some%20path%20with%20blanks/"); final URI uri2 = new URIBuilder() .setScheme("https") .setHost("somehost.com") .setPath("/some path with blanks/") .build(); Assert.assertEquals(uri1, uri2); } @Test public void testAgainstURI() throws Exception { // Check that the URI generated by URI builder agrees with that generated by using URI directly final String scheme="https"; final String host="localhost"; final String specials="/abcd!$&*()_-+.,=:;'~@[]?<>|#^%\"{}\\\u00a3`\u00ac\u00a6xyz"; // N.B. excludes space final URI uri = new URI(scheme, specials, host, 80, specials, specials, specials); final URI bld = new URIBuilder() .setScheme(scheme) .setHost(host) .setUserInfo(specials) .setPath(specials) .setCustomQuery(specials) .setFragment(specials) .build(); Assert.assertEquals(uri.getHost(), bld.getHost()); Assert.assertEquals(uri.getUserInfo(), bld.getUserInfo()); Assert.assertEquals(uri.getPath(), bld.getPath()); Assert.assertEquals(uri.getQuery(), bld.getQuery()); Assert.assertEquals(uri.getFragment(), bld.getFragment()); } @Test public void testAgainstURIEncoded() throws Exception { // Check that the encoded URI generated by URI builder agrees with that generated by using URI directly final String scheme="https"; final String host="localhost"; final String specials="/ abcd!$&*()_-+.,=:;'~<>/@[]|#^%\"{}\\`xyz"; // N.B. excludes \u00a3\u00ac\u00a6 final URI uri = new URI(scheme, specials, host, 80, specials, specials, specials); final URI bld = new URIBuilder() .setScheme(scheme) .setHost(host) .setUserInfo(specials) .setPath(specials) .setCustomQuery(specials) .setFragment(specials) .build(); Assert.assertEquals(uri.getHost(), bld.getHost()); Assert.assertEquals(uri.getRawUserInfo(), bld.getRawUserInfo()); Assert.assertEquals(uri.getRawPath(), bld.getRawPath()); Assert.assertEquals(uri.getRawQuery(), bld.getRawQuery()); Assert.assertEquals(uri.getRawFragment(), bld.getRawFragment()); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/utils/TestURIUtils.java0100644 0000000 0000000 00000041665 12301751654 032266 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import java.net.URI; import java.util.Arrays; import org.apache.http.HttpHost; import org.junit.Assert; import org.junit.Test; /** * This TestCase contains test methods for URI resolving according to RFC 3986. * The examples are listed in section "5.4 Reference Resolution Examples" */ public class TestURIUtils { private final URI baseURI = URI.create("http://a/b/c/d;p?q"); @Test public void testRewrite() throws Exception { final HttpHost target = new HttpHost("thathost", -1); Assert.assertEquals("http://thathost/stuff", URIUtils.rewriteURI( URI.create("http://thishost/stuff"), target).toString()); Assert.assertEquals("/stuff", URIUtils.rewriteURI( URI.create("http://thishost/stuff"), null).toString()); Assert.assertEquals("/", URIUtils.rewriteURI( URI.create("http://thishost//"), null).toString()); Assert.assertEquals("/stuff///morestuff", URIUtils.rewriteURI( URI.create("http://thishost//stuff///morestuff"), null).toString()); Assert.assertEquals("http://thathost/stuff", URIUtils.rewriteURI( URI.create("http://thishost/stuff#crap"), target, true).toString()); Assert.assertEquals("http://thathost/stuff#crap", URIUtils.rewriteURI( URI.create("http://thishost/stuff#crap"), target, false).toString()); Assert.assertEquals("http://thathost/", URIUtils.rewriteURI( URI.create("http://thishost#crap"), target, true).toString()); Assert.assertEquals("http://thathost/#crap", URIUtils.rewriteURI( URI.create("http://thishost#crap"), target, false).toString()); Assert.assertEquals("/stuff/", URIUtils.rewriteURI( URI.create("http://thishost//////////////stuff/"), null).toString()); Assert.assertEquals("http://thathost/stuff", URIUtils.rewriteURI( URI.create("http://thathost/stuff")).toString()); Assert.assertEquals("http://thathost/stuff", URIUtils.rewriteURI( URI.create("http://thathost/stuff#fragment")).toString()); Assert.assertEquals("http://thathost/stuff", URIUtils.rewriteURI( URI.create("http://userinfo@thathost/stuff#fragment")).toString()); Assert.assertEquals("http://thathost/", URIUtils.rewriteURI( URI.create("http://thathost")).toString()); Assert.assertEquals("http://thathost/", URIUtils.rewriteURI( URI.create("http://ThatHost")).toString()); Assert.assertEquals("http://That_Host/", URIUtils.rewriteURI( URI.create("http://That_Host")).toString()); Assert.assertEquals("http://thishost/Fragment_identifier%23Examples", URIUtils.rewriteURI( URI.create("http://thishost/Fragment_identifier%23Examples")).toString()); } @Test public void testRewritePort() throws Exception { HttpHost target = new HttpHost("thathost", 8080); // port should be copied Assert.assertEquals("http://thathost:8080/stuff", URIUtils.rewriteURI( URI.create("http://thishost:80/stuff#crap"), target, true).toString()); Assert.assertEquals("http://thathost:8080/stuff#crap", URIUtils.rewriteURI( URI.create("http://thishost:80/stuff#crap"), target, false).toString()); target = new HttpHost("thathost", -1); // input port should be dropped Assert.assertEquals("http://thathost/stuff", URIUtils.rewriteURI( URI.create("http://thishost:80/stuff#crap"), target, true).toString()); Assert.assertEquals("http://thathost/stuff#crap", URIUtils.rewriteURI( URI.create("http://thishost:80/stuff#crap"), target, false).toString()); } @Test public void testRewriteScheme() throws Exception { final HttpHost target = new HttpHost("thathost", -1, "file"); // scheme should be copied Assert.assertEquals("file://thathost/stuff", URIUtils.rewriteURI( URI.create("http://thishost:80/stuff#crap"), target, true).toString()); } @Test public void testNormalization() { Assert.assertEquals("example://a/b/c/%7Bfoo%7D", URIUtils.resolve(this.baseURI, "eXAMPLE://a/./b/../b/%63/%7bfoo%7d").toString()); Assert.assertEquals("http://www.example.com/%3C", URIUtils.resolve(this.baseURI, "http://www.example.com/%3c").toString()); Assert.assertEquals("http://www.example.com/", URIUtils.resolve(this.baseURI, "HTTP://www.EXAMPLE.com/").toString()); Assert.assertEquals("http://www.example.com/a/", URIUtils.resolve(this.baseURI, "http://www.example.com/a%2f").toString()); Assert.assertEquals("http://www.example.com/?q=%26", URIUtils.resolve(this.baseURI, "http://www.example.com/?q=%26").toString()); Assert.assertEquals("http://www.example.com/%23?q=%26", URIUtils.resolve(this.baseURI, "http://www.example.com/%23?q=%26").toString()); } @Test public void testResolve() { Assert.assertEquals("g:h", URIUtils.resolve(this.baseURI, "g:h").toString()); Assert.assertEquals("http://a/b/c/g", URIUtils.resolve(this.baseURI, "g").toString()); Assert.assertEquals("http://a/b/c/g", URIUtils.resolve(this.baseURI, "./g").toString()); Assert.assertEquals("http://a/b/c/g/", URIUtils.resolve(this.baseURI, "g/").toString()); Assert.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "/g").toString()); Assert.assertEquals("http://g/", URIUtils.resolve(this.baseURI, "//g").toString()); Assert.assertEquals("http://a/b/c/d;p?y", URIUtils.resolve(this.baseURI, "?y").toString()); Assert.assertEquals("http://a/b/c/d;p?y#f", URIUtils.resolve(this.baseURI, "?y#f") .toString()); Assert.assertEquals("http://a/b/c/g?y", URIUtils.resolve(this.baseURI, "g?y").toString()); Assert.assertEquals("http://a/b/c/d;p?q#s", URIUtils.resolve(this.baseURI, "#s") .toString()); Assert.assertEquals("http://a/b/c/g#s", URIUtils.resolve(this.baseURI, "g#s").toString()); Assert.assertEquals("http://a/b/c/g?y#s", URIUtils.resolve(this.baseURI, "g?y#s") .toString()); Assert.assertEquals("http://a/b/c/;x", URIUtils.resolve(this.baseURI, ";x").toString()); Assert.assertEquals("http://a/b/c/g;x", URIUtils.resolve(this.baseURI, "g;x").toString()); Assert.assertEquals("http://a/b/c/g;x?y#s", URIUtils.resolve(this.baseURI, "g;x?y#s") .toString()); Assert.assertEquals("http://a/b/c/d;p?q", URIUtils.resolve(this.baseURI, "").toString()); Assert.assertEquals("http://a/b/c/", URIUtils.resolve(this.baseURI, ".").toString()); Assert.assertEquals("http://a/b/c/", URIUtils.resolve(this.baseURI, "./").toString()); Assert.assertEquals("http://a/b/", URIUtils.resolve(this.baseURI, "..").toString()); Assert.assertEquals("http://a/b/", URIUtils.resolve(this.baseURI, "../").toString()); Assert.assertEquals("http://a/b/g", URIUtils.resolve(this.baseURI, "../g").toString()); Assert.assertEquals("http://a/", URIUtils.resolve(this.baseURI, "../..").toString()); Assert.assertEquals("http://a/", URIUtils.resolve(this.baseURI, "../../").toString()); Assert.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "../../g").toString()); Assert.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "../../../g").toString()); Assert.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "../../../../g") .toString()); Assert.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "/./g").toString()); Assert.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "/../g").toString()); Assert.assertEquals("http://a/b/c/g.", URIUtils.resolve(this.baseURI, "g.").toString()); Assert.assertEquals("http://a/b/c/.g", URIUtils.resolve(this.baseURI, ".g").toString()); Assert.assertEquals("http://a/b/c/g..", URIUtils.resolve(this.baseURI, "g..").toString()); Assert.assertEquals("http://a/b/c/..g", URIUtils.resolve(this.baseURI, "..g").toString()); Assert.assertEquals("http://a/b/g", URIUtils.resolve(this.baseURI, "./../g").toString()); Assert.assertEquals("http://a/b/c/g/", URIUtils.resolve(this.baseURI, "./g/.").toString()); Assert.assertEquals("http://a/b/c/g/h", URIUtils.resolve(this.baseURI, "g/./h").toString()); Assert.assertEquals("http://a/b/c/h", URIUtils.resolve(this.baseURI, "g/../h").toString()); Assert.assertEquals("http://a/b/c/g;x=1/y", URIUtils.resolve(this.baseURI, "g;x=1/./y") .toString()); Assert.assertEquals("http://a/b/c/y", URIUtils.resolve(this.baseURI, "g;x=1/../y") .toString()); Assert.assertEquals("http://a/b/c/g?y/./x", URIUtils.resolve(this.baseURI, "g?y/./x") .toString()); Assert.assertEquals("http://a/b/c/g?y/../x", URIUtils.resolve(this.baseURI, "g?y/../x") .toString()); Assert.assertEquals("http://a/b/c/g#s/./x", URIUtils.resolve(this.baseURI, "g#s/./x") .toString()); Assert.assertEquals("http://a/b/c/g#s/../x", URIUtils.resolve(this.baseURI, "g#s/../x") .toString()); Assert.assertEquals("http:g", URIUtils.resolve(this.baseURI, "http:g").toString()); // examples from section 5.2.4 Assert.assertEquals("http://s/a/g", URIUtils.resolve(this.baseURI, "http://s/a/b/c/./../../g").toString()); Assert.assertEquals("http://s/mid/6", URIUtils.resolve(this.baseURI, "http://s/mid/content=5/../6").toString()); } @Test public void testResolveOpaque() { Assert.assertEquals("example://a/b/c/%7Bfoo%7D", URIUtils.resolve(this.baseURI, "eXAMPLE://a/./b/../b/%63/%7bfoo%7d").toString()); Assert.assertEquals("file://localhost/etc/fstab", URIUtils.resolve(this.baseURI, "file://localhost/etc/fstab").toString()); Assert.assertEquals("file:///etc/fstab", URIUtils.resolve(this.baseURI, "file:///etc/fstab").toString()); Assert.assertEquals("file://localhost/c:/WINDOWS/clock.avi", URIUtils.resolve(this.baseURI, "file://localhost/c:/WINDOWS/clock.avi").toString()); Assert.assertEquals("file:///c:/WINDOWS/clock.avi", URIUtils.resolve(this.baseURI, "file:///c:/WINDOWS/clock.avi").toString()); Assert.assertEquals("file://hostname/path/to/the%20file.txt", URIUtils.resolve(this.baseURI, "file://hostname/path/to/the%20file.txt").toString()); Assert.assertEquals("file:///c:/path/to/the%20file.txt", URIUtils.resolve(this.baseURI, "file:///c:/path/to/the%20file.txt").toString()); Assert.assertEquals("urn:issn:1535-3613", URIUtils.resolve(this.baseURI, "urn:issn:1535-3613").toString()); Assert.assertEquals("mailto:user@example.com", URIUtils.resolve(this.baseURI, "mailto:user@example.com").toString()); Assert.assertEquals("ftp://example.org/resource.txt", URIUtils.resolve(this.baseURI, "ftp://example.org/resource.txt").toString()); } @Test public void testExtractHost() throws Exception { Assert.assertEquals(new HttpHost("localhost"), URIUtils.extractHost(new URI("http://localhost/abcd"))); Assert.assertEquals(new HttpHost("localhost"), URIUtils.extractHost(new URI("http://localhost/abcd%3A"))); Assert.assertEquals(new HttpHost("local_host"), URIUtils.extractHost(new URI("http://local_host/abcd"))); Assert.assertEquals(new HttpHost("local_host"), URIUtils.extractHost(new URI("http://local_host/abcd%3A"))); Assert.assertEquals(new HttpHost("localhost",8), URIUtils.extractHost(new URI("http://localhost:8/abcd"))); Assert.assertEquals(new HttpHost("local_host",8), URIUtils.extractHost(new URI("http://local_host:8/abcd"))); // URI seems to OK with missing port number Assert.assertEquals(new HttpHost("localhost",-1),URIUtils.extractHost( new URI("http://localhost:/abcd"))); Assert.assertEquals(new HttpHost("local_host",-1),URIUtils.extractHost( new URI("http://local_host:/abcd"))); Assert.assertEquals(new HttpHost("localhost",8080), URIUtils.extractHost(new URI("http://user:pass@localhost:8080/abcd"))); Assert.assertEquals(new HttpHost("local_host",8080), URIUtils.extractHost(new URI("http://user:pass@local_host:8080/abcd"))); Assert.assertEquals(new HttpHost("localhost",8080),URIUtils.extractHost( new URI("http://@localhost:8080/abcd"))); Assert.assertEquals(new HttpHost("local_host",8080),URIUtils.extractHost( new URI("http://@local_host:8080/abcd"))); Assert.assertEquals(new HttpHost("[2a00:1450:400c:c01::69]",8080), URIUtils.extractHost(new URI("http://[2a00:1450:400c:c01::69]:8080/"))); Assert.assertEquals(new HttpHost("localhost",8080), URIUtils.extractHost(new URI("http://localhost:8080/;sessionid=stuff/abcd"))); Assert.assertEquals(new HttpHost("localhost",8080), URIUtils.extractHost(new URI("http://localhost:8080;sessionid=stuff/abcd"))); Assert.assertEquals(new HttpHost("localhost",-1), URIUtils.extractHost(new URI("http://localhost:;sessionid=stuff/abcd"))); } @Test public void testHttpLocationWithRelativeFragment() throws Exception { final HttpHost target = new HttpHost("localhost", -1, "http"); final URI requestURI = new URI("/stuff#blahblah"); final URI location = URIUtils.resolve(requestURI, target, null); final URI expectedURI = new URIBuilder(requestURI) .setHost(target.getHostName()) .setScheme(target.getSchemeName()) .build(); Assert.assertEquals(expectedURI, location); } @Test public void testHttpLocationWithAbsoluteFragment() throws Exception { final HttpHost target = new HttpHost("localhost", 80, "http"); final URI requestURI = new URIBuilder() .setHost(target.getHostName()) .setScheme(target.getSchemeName()) .setPath("/stuff") .setFragment("blahblah") .build(); final URI location = URIUtils.resolve(requestURI, target, null); final URI expectedURI = requestURI; Assert.assertEquals(expectedURI, location); } @Test public void testHttpLocationRedirect() throws Exception { final HttpHost target = new HttpHost("localhost", -1, "http"); final URI requestURI = new URI("/People.htm#tim"); final URI redirect = new URI("http://localhost/people.html"); final URI location = URIUtils.resolve(requestURI, target, Arrays.asList(redirect)); final URI expectedURI = new URIBuilder() .setHost(target.getHostName()) .setScheme(target.getSchemeName()) .setPath("/people.html") .setFragment("tim") .build(); Assert.assertEquals(expectedURI, location); } @Test public void testHttpLocationWithRedirectFragment() throws Exception { final HttpHost target = new HttpHost("localhost", -1, "http"); final URI requestURI = new URI("/~tim"); final URI redirect1 = new URI("http://localhost/People.htm#tim"); final URI redirect2 = new URI("http://localhost/people.html"); final URI location = URIUtils.resolve(requestURI, target, Arrays.asList(redirect1, redirect2)); final URI expectedURI = new URIBuilder() .setHost(target.getHostName()) .setScheme(target.getSchemeName()) .setPath("/people.html") .setFragment("tim") .build(); Assert.assertEquals(expectedURI, location); } } ././@LongLink0100644 0000000 0000000 00000000153 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/utils/TestURLEncodedUtils.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/client/utils/TestURLEncodedUtil0100644 0000000 0000000 00000041154 12301751654 032441 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.utils; import java.net.URI; import java.util.ArrayList; import java.util.List; import org.apache.http.Consts; import org.apache.http.NameValuePair; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HTTP; import org.junit.Assert; import org.junit.Test; public class TestURLEncodedUtils { @Test public void testParseURLCodedContent() throws Exception { List result; result = parse(""); Assert.assertTrue(result.isEmpty()); result = parse("Name0"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name0", null); result = parse("Name1=Value1"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name1", "Value1"); result = parse("Name2="); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name2", ""); result = parse("Name3"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name3", null); result = parse("Name4=Value%204%21"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name4", "Value 4!"); result = parse("Name4=Value%2B4%21"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name4", "Value+4!"); result = parse("Name4=Value%204%21%20%214"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name4", "Value 4! !4"); result = parse("Name5=aaa&Name6=bbb"); Assert.assertEquals(2, result.size()); assertNameValuePair(result.get(0), "Name5", "aaa"); assertNameValuePair(result.get(1), "Name6", "bbb"); result = parse("Name7=aaa&Name7=b%2Cb&Name7=ccc"); Assert.assertEquals(3, result.size()); assertNameValuePair(result.get(0), "Name7", "aaa"); assertNameValuePair(result.get(1), "Name7", "b,b"); assertNameValuePair(result.get(2), "Name7", "ccc"); result = parse("Name8=xx%2C%20%20yy%20%20%2Czz"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name8", "xx, yy ,zz"); result = parse("price=10%20%E2%82%AC"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "price", "10 \u20AC"); } @Test public void testParseURLCodedContentString() throws Exception { List result; result = parseString(""); Assert.assertTrue(result.isEmpty()); result = parseString("Name0"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name0", null); result = parseString("Name1=Value1"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name1", "Value1"); result = parseString("Name2="); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name2", ""); result = parseString("Name3"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name3", null); result = parseString("Name4=Value%204%21"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name4", "Value 4!"); result = parseString("Name4=Value%2B4%21"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name4", "Value+4!"); result = parseString("Name4=Value%204%21%20%214"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name4", "Value 4! !4"); result = parseString("Name5=aaa&Name6=bbb"); Assert.assertEquals(2, result.size()); assertNameValuePair(result.get(0), "Name5", "aaa"); assertNameValuePair(result.get(1), "Name6", "bbb"); result = parseString("Name7=aaa&Name7=b%2Cb&Name7=ccc"); Assert.assertEquals(3, result.size()); assertNameValuePair(result.get(0), "Name7", "aaa"); assertNameValuePair(result.get(1), "Name7", "b,b"); assertNameValuePair(result.get(2), "Name7", "ccc"); result = parseString("Name8=xx%2C%20%20yy%20%20%2Czz"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name8", "xx, yy ,zz"); result = parseString("price=10%20%E2%82%AC"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "price", "10 \u20AC"); } @Test public void testParseInvalidURLCodedContent() throws Exception { List result; result = parse("name=%"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "name", "%"); result = parse("name=%a"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "name", "%a"); result = parse("name=%wa%20"); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "name", "%wa "); } @Test public void testParseEntity() throws Exception { final StringEntity entity = new StringEntity("Name1=Value1"); entity.setContentType(URLEncodedUtils.CONTENT_TYPE); final List result = URLEncodedUtils.parse(entity); Assert.assertEquals(1, result.size()); assertNameValuePair(result.get(0), "Name1", "Value1"); entity.setContentType("text/test"); Assert.assertTrue(URLEncodedUtils.parse(entity).isEmpty()); } private static final int SWISS_GERMAN_HELLO [] = { 0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4 }; private static final int RUSSIAN_HELLO [] = { 0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438, 0x432, 0x435, 0x442 }; private static String constructString(final int [] unicodeChars) { final StringBuffer buffer = new StringBuffer(); if (unicodeChars != null) { for (final int unicodeChar : unicodeChars) { buffer.append((char)unicodeChar); } } return buffer.toString(); } @Test public void testParseUTF8Entity() throws Exception { final String ru_hello = constructString(RUSSIAN_HELLO); final String ch_hello = constructString(SWISS_GERMAN_HELLO); final List parameters = new ArrayList(); parameters.add(new BasicNameValuePair("russian", ru_hello)); parameters.add(new BasicNameValuePair("swiss", ch_hello)); final String s = URLEncodedUtils.format(parameters, Consts.UTF_8); Assert.assertEquals("russian=%D0%92%D1%81%D0%B5%D0%BC_%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82" + "&swiss=Gr%C3%BCezi_z%C3%A4m%C3%A4", s); final StringEntity entity = new StringEntity(s, ContentType.create( URLEncodedUtils.CONTENT_TYPE, Consts.UTF_8)); final List result = URLEncodedUtils.parse(entity); Assert.assertEquals(2, result.size()); assertNameValuePair(result.get(0), "russian", ru_hello); assertNameValuePair(result.get(1), "swiss", ch_hello); } @Test public void testParseUTF8Ampersand1String() throws Exception { final String ru_hello = constructString(RUSSIAN_HELLO); final String ch_hello = constructString(SWISS_GERMAN_HELLO); final List parameters = new ArrayList(); parameters.add(new BasicNameValuePair("russian", ru_hello)); parameters.add(new BasicNameValuePair("swiss", ch_hello)); final String s = URLEncodedUtils.format(parameters, Consts.UTF_8); final List result = URLEncodedUtils.parse(s, Consts.UTF_8); Assert.assertEquals(2, result.size()); assertNameValuePair(result.get(0), "russian", ru_hello); assertNameValuePair(result.get(1), "swiss", ch_hello); } @Test public void testParseUTF8Ampersand2String() throws Exception { testParseUTF8String('&'); } @Test public void testParseUTF8SemicolonString() throws Exception { testParseUTF8String(';'); } private void testParseUTF8String(final char parameterSeparator) throws Exception { final String ru_hello = constructString(RUSSIAN_HELLO); final String ch_hello = constructString(SWISS_GERMAN_HELLO); final List parameters = new ArrayList(); parameters.add(new BasicNameValuePair("russian", ru_hello)); parameters.add(new BasicNameValuePair("swiss", ch_hello)); final String s = URLEncodedUtils.format(parameters, parameterSeparator, Consts.UTF_8); final List result1 = URLEncodedUtils.parse(s, Consts.UTF_8); Assert.assertEquals(2, result1.size()); assertNameValuePair(result1.get(0), "russian", ru_hello); assertNameValuePair(result1.get(1), "swiss", ch_hello); final List result2 = URLEncodedUtils.parse(s, Consts.UTF_8, parameterSeparator); Assert.assertEquals(result1, result2); } @Test public void testParseEntityDefaultContentType() throws Exception { final String ch_hello = constructString(SWISS_GERMAN_HELLO); final String us_hello = "hi there"; final List parameters = new ArrayList(); parameters.add(new BasicNameValuePair("english", us_hello)); parameters.add(new BasicNameValuePair("swiss", ch_hello)); final String s = URLEncodedUtils.format(parameters, HTTP.DEF_CONTENT_CHARSET); Assert.assertEquals("english=hi+there&swiss=Gr%FCezi_z%E4m%E4", s); final StringEntity entity = new StringEntity(s, ContentType.create( URLEncodedUtils.CONTENT_TYPE, HTTP.DEF_CONTENT_CHARSET)); final List result = URLEncodedUtils.parse(entity); Assert.assertEquals(2, result.size()); assertNameValuePair(result.get(0), "english", us_hello); assertNameValuePair(result.get(1), "swiss", ch_hello); } @Test public void testIsEncoded() throws Exception { final StringEntity entity = new StringEntity("..."); entity.setContentType(URLEncodedUtils.CONTENT_TYPE); Assert.assertTrue(URLEncodedUtils.isEncoded(entity)); entity.setContentType(URLEncodedUtils.CONTENT_TYPE + "; charset=US-ASCII"); Assert.assertTrue(URLEncodedUtils.isEncoded(entity)); entity.setContentType("text/test"); Assert.assertFalse(URLEncodedUtils.isEncoded(entity)); } @Test public void testFormat() throws Exception { final List params = new ArrayList (); Assert.assertEquals(0, URLEncodedUtils.format(params, Consts.ASCII).length()); params.clear(); params.add(new BasicNameValuePair("Name0", null)); Assert.assertEquals("Name0", URLEncodedUtils.format(params, Consts.ASCII)); params.clear(); params.add(new BasicNameValuePair("Name1", "Value1")); Assert.assertEquals("Name1=Value1", URLEncodedUtils.format(params, Consts.ASCII)); params.clear(); params.add(new BasicNameValuePair("Name2", "")); Assert.assertEquals("Name2=", URLEncodedUtils.format(params, Consts.ASCII)); params.clear(); params.add(new BasicNameValuePair("Name4", "Value 4&")); Assert.assertEquals("Name4=Value+4%26", URLEncodedUtils.format(params, Consts.ASCII)); params.clear(); params.add(new BasicNameValuePair("Name4", "Value+4&")); Assert.assertEquals("Name4=Value%2B4%26", URLEncodedUtils.format(params, Consts.ASCII)); params.clear(); params.add(new BasicNameValuePair("Name4", "Value 4& =4")); Assert.assertEquals("Name4=Value+4%26+%3D4", URLEncodedUtils.format(params, Consts.ASCII)); params.clear(); params.add(new BasicNameValuePair("Name5", "aaa")); params.add(new BasicNameValuePair("Name6", "bbb")); Assert.assertEquals("Name5=aaa&Name6=bbb", URLEncodedUtils.format(params, Consts.ASCII)); params.clear(); params.add(new BasicNameValuePair("Name7", "aaa")); params.add(new BasicNameValuePair("Name7", "b,b")); params.add(new BasicNameValuePair("Name7", "ccc")); Assert.assertEquals("Name7=aaa&Name7=b%2Cb&Name7=ccc", URLEncodedUtils.format(params, Consts.ASCII)); Assert.assertEquals("Name7=aaa&Name7=b%2Cb&Name7=ccc", URLEncodedUtils.format(params, '&', Consts.ASCII)); Assert.assertEquals("Name7=aaa;Name7=b%2Cb;Name7=ccc", URLEncodedUtils.format(params, ';', Consts.ASCII)); params.clear(); params.add(new BasicNameValuePair("Name8", "xx, yy ,zz")); Assert.assertEquals("Name8=xx%2C++yy++%2Czz", URLEncodedUtils.format(params, Consts.ASCII)); } @Test public void testFormatString() throws Exception { // as above, using String final List params = new ArrayList (); Assert.assertEquals(0, URLEncodedUtils.format(params, "US-ASCII").length()); params.clear(); params.add(new BasicNameValuePair("Name0", null)); Assert.assertEquals("Name0", URLEncodedUtils.format(params, "US-ASCII")); params.clear(); params.add(new BasicNameValuePair("Name1", "Value1")); Assert.assertEquals("Name1=Value1", URLEncodedUtils.format(params, "US-ASCII")); params.clear(); params.add(new BasicNameValuePair("Name2", "")); Assert.assertEquals("Name2=", URLEncodedUtils.format(params, "US-ASCII")); params.clear(); params.add(new BasicNameValuePair("Name4", "Value 4&")); Assert.assertEquals("Name4=Value+4%26", URLEncodedUtils.format(params, "US-ASCII")); params.clear(); params.add(new BasicNameValuePair("Name4", "Value+4&")); Assert.assertEquals("Name4=Value%2B4%26", URLEncodedUtils.format(params, "US-ASCII")); params.clear(); params.add(new BasicNameValuePair("Name4", "Value 4& =4")); Assert.assertEquals("Name4=Value+4%26+%3D4", URLEncodedUtils.format(params, "US-ASCII")); params.clear(); params.add(new BasicNameValuePair("Name5", "aaa")); params.add(new BasicNameValuePair("Name6", "bbb")); Assert.assertEquals("Name5=aaa&Name6=bbb", URLEncodedUtils.format(params, "US-ASCII")); params.clear(); params.add(new BasicNameValuePair("Name7", "aaa")); params.add(new BasicNameValuePair("Name7", "b,b")); params.add(new BasicNameValuePair("Name7", "ccc")); Assert.assertEquals("Name7=aaa&Name7=b%2Cb&Name7=ccc", URLEncodedUtils.format(params, "US-ASCII")); params.clear(); params.add(new BasicNameValuePair("Name8", "xx, yy ,zz")); Assert.assertEquals("Name8=xx%2C++yy++%2Czz", URLEncodedUtils.format(params, "US-ASCII")); } private List parse (final String params) { return URLEncodedUtils.parse(params, Consts.UTF_8); } private List parseString (final String uri) throws Exception { return URLEncodedUtils.parse(new URI("?"+uri), "UTF-8"); } private static void assertNameValuePair ( final NameValuePair parameter, final String expectedName, final String expectedValue) { Assert.assertEquals(parameter.getName(), expectedName); Assert.assertEquals(parameter.getValue(), expectedValue); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/0040755 0000000 0000000 00000000000 12301751653 025410 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/TestEofSensorInputStream.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/TestEofSensorInputStream.j0100644 0000000 0000000 00000017006 12301751653 032523 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import java.io.IOException; import java.io.InputStream; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; public class TestEofSensorInputStream { private InputStream instream; private EofSensorWatcher eofwatcher; private EofSensorInputStream eofstream; @Before public void setup() throws Exception { instream = Mockito.mock(InputStream.class); eofwatcher = Mockito.mock(EofSensorWatcher.class); eofstream = new EofSensorInputStream(instream, eofwatcher); } @Test public void testClose() throws Exception { Mockito.when(eofwatcher.streamClosed(Mockito.any())).thenReturn(Boolean.TRUE); eofstream.close(); Assert.assertTrue(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(instream, Mockito.times(1)).close(); Mockito.verify(eofwatcher).streamClosed(instream); eofstream.close(); } @Test public void testCloseIOError() throws Exception { Mockito.when(eofwatcher.streamClosed(Mockito.any())).thenThrow(new IOException()); try { eofstream.close(); Assert.fail("IOException expected"); } catch (final IOException ex) { } Assert.assertTrue(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(eofwatcher).streamClosed(instream); } @Test public void testReleaseConnection() throws Exception { Mockito.when(eofwatcher.streamClosed(Mockito.any())).thenReturn(Boolean.TRUE); eofstream.releaseConnection(); Assert.assertTrue(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(instream, Mockito.times(1)).close(); Mockito.verify(eofwatcher).streamClosed(instream); eofstream.releaseConnection(); } @Test public void testAbortConnection() throws Exception { Mockito.when(eofwatcher.streamAbort(Mockito.any())).thenReturn(Boolean.TRUE); eofstream.abortConnection(); Assert.assertTrue(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(instream, Mockito.times(1)).close(); Mockito.verify(eofwatcher).streamAbort(instream); eofstream.abortConnection(); } @Test public void testAbortConnectionIOError() throws Exception { Mockito.when(eofwatcher.streamAbort(Mockito.any())).thenThrow(new IOException()); try { eofstream.abortConnection(); Assert.fail("IOException expected"); } catch (final IOException ex) { } Assert.assertTrue(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(eofwatcher).streamAbort(instream); } @Test public void testRead() throws Exception { Mockito.when(eofwatcher.eofDetected(Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(instream.read()).thenReturn(0, -1); Assert.assertEquals(0, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNotNull(eofstream.getWrappedStream()); Mockito.verify(eofwatcher, Mockito.never()).eofDetected(instream); Assert.assertEquals(-1, eofstream.read()); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(instream, Mockito.times(1)).close(); Mockito.verify(eofwatcher).eofDetected(instream); Assert.assertEquals(-1, eofstream.read()); } @Test public void testReadIOError() throws Exception { Mockito.when(eofwatcher.eofDetected(Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(instream.read()).thenThrow(new IOException()); try { eofstream.read(); Assert.fail("IOException expected"); } catch (final IOException ex) { } Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(eofwatcher).streamAbort(instream); } @Test public void testReadByteArray() throws Exception { Mockito.when(eofwatcher.eofDetected(Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(instream.read(Mockito.any(), Mockito.anyInt(), Mockito.anyInt())) .thenReturn(1, -1); final byte[] tmp = new byte[1]; Assert.assertEquals(1, eofstream.read(tmp)); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNotNull(eofstream.getWrappedStream()); Mockito.verify(eofwatcher, Mockito.never()).eofDetected(instream); Assert.assertEquals(-1, eofstream.read(tmp)); Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(instream, Mockito.times(1)).close(); Mockito.verify(eofwatcher).eofDetected(instream); Assert.assertEquals(-1, eofstream.read(tmp)); } @Test public void testReadByteArrayIOError() throws Exception { Mockito.when(eofwatcher.eofDetected(Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(instream.read(Mockito.any(), Mockito.anyInt(), Mockito.anyInt())) .thenThrow(new IOException()); final byte[] tmp = new byte[1]; try { eofstream.read(tmp); Assert.fail("IOException expected"); } catch (final IOException ex) { } Assert.assertFalse(eofstream.isSelfClosed()); Assert.assertNull(eofstream.getWrappedStream()); Mockito.verify(eofwatcher).streamAbort(instream); } @Test public void testReadAfterAbort() throws Exception { Mockito.when(eofwatcher.streamAbort(Mockito.any())).thenReturn(Boolean.TRUE); eofstream.abortConnection(); try { eofstream.read(); Assert.fail("IOException expected"); } catch (final IOException ex) { } final byte[] tmp = new byte[1]; try { eofstream.read(tmp); Assert.fail("IOException expected"); } catch (final IOException ex) { } } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/TestExceptions.java0100644 0000000 0000000 00000012460 12301751653 031234 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn; import org.apache.http.HttpHost; import org.junit.Assert; import org.junit.Test; import java.io.IOException; import java.net.InetAddress; /** * Unit tests for exceptions. * Trivial, but it looks better in the Clover reports. */ public class TestExceptions { @Test public void testConnectTimeoutExceptionNullMessage() { final ConnectTimeoutException ctx = new ConnectTimeoutException(); Assert.assertNull(ctx.getMessage()); } @Test public void testConnectTimeoutExceptionSimpleMessage() { final ConnectTimeoutException ctx = new ConnectTimeoutException("sample exception message"); Assert.assertEquals("sample exception message", ctx.getMessage()); } @Test public void testConnectTimeoutExceptionFromNullCause() { final ConnectTimeoutException ctx = new ConnectTimeoutException(null, null); Assert.assertEquals("Connect to remote host timed out", ctx.getMessage()); } @Test public void testConnectTimeoutExceptionFromCause() { final IOException cause = new IOException("something awful"); final ConnectTimeoutException ctx = new ConnectTimeoutException(cause, null); Assert.assertEquals("Connect to remote host failed: something awful", ctx.getMessage()); } @Test public void testConnectTimeoutExceptionFromCauseAndHost() { final HttpHost target = new HttpHost("localhost"); final IOException cause = new IOException(); final ConnectTimeoutException ctx = new ConnectTimeoutException(cause, target); Assert.assertEquals("Connect to localhost timed out", ctx.getMessage()); } @Test public void testConnectTimeoutExceptionFromCauseHostAndRemoteAddress() throws Exception { final HttpHost target = new HttpHost("localhost"); final InetAddress remoteAddress = InetAddress.getByAddress(new byte[] {1,2,3,4}); final IOException cause = new IOException(); final ConnectTimeoutException ctx = new ConnectTimeoutException(cause, target, remoteAddress); Assert.assertEquals("Connect to localhost [/1.2.3.4] timed out", ctx.getMessage()); } @Test public void testHttpHostConnectExceptionFromNullCause() { final HttpHostConnectException ctx = new HttpHostConnectException(null, null, (InetAddress [])null); Assert.assertEquals("Connect to remote host refused", ctx.getMessage()); } @Test public void testHttpHostConnectExceptionFromCause() { final IOException cause = new IOException("something awful"); final HttpHostConnectException ctx = new HttpHostConnectException(cause, null); Assert.assertEquals("Connect to remote host failed: something awful", ctx.getMessage()); } @Test public void testHttpHostConnectExceptionFromCauseAndHost() { final HttpHost target = new HttpHost("localhost"); final IOException cause = new IOException(); final HttpHostConnectException ctx = new HttpHostConnectException(cause, target); Assert.assertEquals("Connect to localhost refused", ctx.getMessage()); } @Test public void testHttpHostConnectExceptionFromCauseHostAndRemoteAddress() throws Exception { final HttpHost target = new HttpHost("localhost"); final InetAddress remoteAddress1 = InetAddress.getByAddress(new byte[] {1,2,3,4}); final InetAddress remoteAddress2 = InetAddress.getByAddress(new byte[] {5,6,7,8}); final IOException cause = new IOException(); final HttpHostConnectException ctx = new HttpHostConnectException(cause, target, remoteAddress1, remoteAddress2); Assert.assertEquals("Connect to localhost [/1.2.3.4, /5.6.7.8] refused", ctx.getMessage()); } @Test public void testConnectionPoolTimeoutException() { final String msg = "sample exception message"; ConnectionPoolTimeoutException cptx = new ConnectionPoolTimeoutException(msg); Assert.assertFalse(cptx.toString().indexOf(msg) < 0); Assert.assertSame(msg, cptx.getMessage()); cptx = new ConnectionPoolTimeoutException(); Assert.assertNull(cptx.getMessage()); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/routing/0040755 0000000 0000000 00000000000 12301751653 027077 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000145 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/routing/TestHttpRoute.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/routing/TestHttpRoute.java0100644 0000000 0000000 00000063217 12301751653 032546 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.routing; import java.net.InetAddress; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.apache.http.HttpHost; import org.apache.http.conn.routing.RouteInfo.LayerType; import org.apache.http.conn.routing.RouteInfo.TunnelType; import org.junit.Assert; import org.junit.Test; /** * Tests for {@link HttpRoute}. */ public class TestHttpRoute { // a selection of constants for generating routes public final static HttpHost TARGET1 = new HttpHost("target1.test.invalid"); public final static HttpHost TARGET2 = new HttpHost("target2.test.invalid", 8080); // It is not necessary to have extra targets for https. // The 'layered' and 'secure' flags are specified explicitly // for routes, they will not be determined from the scheme. public final static HttpHost PROXY1 = new HttpHost("proxy1.test.invalid"); public final static HttpHost PROXY2 = new HttpHost("proxy2.test.invalid", 1080); public final static HttpHost PROXY3 = new HttpHost("proxy3.test.invalid", 88); public final static InetAddress LOCAL41; public final static InetAddress LOCAL42; public final static InetAddress LOCAL61; public final static InetAddress LOCAL62; // need static initializer to deal with exceptions static { try { LOCAL41 = InetAddress.getByAddress(new byte[]{ 127, 0, 0, 1 }); LOCAL42 = InetAddress.getByAddress(new byte[]{ 127, 0, 0, 2 }); LOCAL61 = InetAddress.getByAddress(new byte[]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }); LOCAL62 = InetAddress.getByAddress(new byte[]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }); } catch (final Exception x) { throw new ExceptionInInitializerError(x); } } @Test public void testCstrFullRoute() { // create a route with all arguments and check the details final HttpHost[] chain3 = { PROXY1, PROXY2, PROXY3 }; final HttpRoute route = new HttpRoute(TARGET1, LOCAL41, chain3, false, TunnelType.PLAIN, LayerType.PLAIN); Assert.assertEquals("wrong target", TARGET1, route.getTargetHost()); Assert.assertEquals("wrong local address", LOCAL41, route.getLocalAddress()); Assert.assertEquals("wrong proxy host", PROXY1, route.getProxyHost()); Assert.assertEquals("wrong hop count", 4, route.getHopCount()); Assert.assertEquals("wrong hop 0", PROXY1, route.getHopTarget(0)); Assert.assertEquals("wrong hop 1", PROXY2, route.getHopTarget(1)); Assert.assertEquals("wrong hop 2", PROXY3, route.getHopTarget(2)); Assert.assertEquals("wrong hop 3", TARGET1, route.getHopTarget(3)); Assert.assertFalse("wrong flag: secured", route.isSecure()); Assert.assertFalse("wrong flag: tunnelled", route.isTunnelled()); Assert.assertFalse("wrong flag: layered", route.isLayered()); final String routestr = route.toString(); Assert.assertTrue("missing target in toString", routestr.indexOf(TARGET1.getHostName()) >= 0); Assert.assertTrue("missing local address in toString", routestr.indexOf(LOCAL41.toString()) >= 0); Assert.assertTrue("missing proxy 1 in toString", routestr.indexOf(PROXY1.getHostName()) >= 0); Assert.assertTrue("missing proxy 2 in toString", routestr.indexOf(PROXY2.getHostName()) >= 0); Assert.assertTrue("missing proxy 3 in toString", routestr.indexOf(PROXY3.getHostName()) >= 0); } @Test public void testCstrFullFlags() { // tests the flag parameters in the full-blown constructor final HttpHost[] chain3 = { PROXY1, PROXY2, PROXY3 }; final HttpRoute routefff = new HttpRoute (TARGET1, LOCAL41, chain3, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute routefft = new HttpRoute (TARGET1, LOCAL41, chain3, false, TunnelType.PLAIN, LayerType.LAYERED); final HttpRoute routeftf = new HttpRoute (TARGET1, LOCAL41, chain3, false, TunnelType.TUNNELLED, LayerType.PLAIN); final HttpRoute routeftt = new HttpRoute (TARGET1, LOCAL41, chain3, false, TunnelType.TUNNELLED, LayerType.LAYERED); final HttpRoute routetff = new HttpRoute (TARGET1, LOCAL41, chain3, true, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute routetft = new HttpRoute (TARGET1, LOCAL41, chain3, true, TunnelType.PLAIN, LayerType.LAYERED); final HttpRoute routettf = new HttpRoute (TARGET1, LOCAL41, chain3, true, TunnelType.TUNNELLED, LayerType.PLAIN); final HttpRoute routettt = new HttpRoute (TARGET1, LOCAL41, chain3, true, TunnelType.TUNNELLED, LayerType.LAYERED); Assert.assertFalse("routefff.secure", routefff.isSecure()); Assert.assertFalse("routefff.tunnel", routefff.isTunnelled()); Assert.assertFalse("routefff.layer" , routefff.isLayered()); Assert.assertFalse("routefft.secure", routefft.isSecure()); Assert.assertFalse("routefft.tunnel", routefft.isTunnelled()); Assert.assertTrue ("routefft.layer" , routefft.isLayered()); Assert.assertFalse("routeftf.secure", routeftf.isSecure()); Assert.assertTrue ("routeftf.tunnel", routeftf.isTunnelled()); Assert.assertFalse("routeftf.layer" , routeftf.isLayered()); Assert.assertFalse("routeftt.secure", routeftt.isSecure()); Assert.assertTrue ("routeftt.tunnel", routeftt.isTunnelled()); Assert.assertTrue ("routeftt.layer" , routeftt.isLayered()); Assert.assertTrue ("routetff.secure", routetff.isSecure()); Assert.assertFalse("routetff.tunnel", routetff.isTunnelled()); Assert.assertFalse("routetff.layer" , routetff.isLayered()); Assert.assertTrue ("routetft.secure", routetft.isSecure()); Assert.assertFalse("routetft.tunnel", routetft.isTunnelled()); Assert.assertTrue ("routetft.layer" , routetft.isLayered()); Assert.assertTrue ("routettf.secure", routettf.isSecure()); Assert.assertTrue ("routettf.tunnel", routettf.isTunnelled()); Assert.assertFalse("routettf.layer" , routettf.isLayered()); Assert.assertTrue ("routettt.secure", routettt.isSecure()); Assert.assertTrue ("routettt.tunnel", routettt.isTunnelled()); Assert.assertTrue ("routettt.layer" , routettt.isLayered()); final Set routes = new HashSet(); routes.add(routefff); routes.add(routefft); routes.add(routeftf); routes.add(routeftt); routes.add(routetff); routes.add(routetft); routes.add(routettf); routes.add(routettt); Assert.assertEquals("some flagged routes are equal", 8, routes.size()); // we can't test hashCode in general due to its dependency // on InetAddress and HttpHost, but we can check for the flags final Set routecodes = new HashSet(); routecodes.add(Integer.valueOf(routefff.hashCode())); routecodes.add(Integer.valueOf(routefft.hashCode())); routecodes.add(Integer.valueOf(routeftf.hashCode())); routecodes.add(Integer.valueOf(routeftt.hashCode())); routecodes.add(Integer.valueOf(routetff.hashCode())); routecodes.add(Integer.valueOf(routetft.hashCode())); routecodes.add(Integer.valueOf(routettf.hashCode())); routecodes.add(Integer.valueOf(routettt.hashCode())); Assert.assertEquals("some flagged routes have same hashCode", 8, routecodes.size()); final Set routestrings = new HashSet(); routestrings.add(routefff.toString()); routestrings.add(routefft.toString()); routestrings.add(routeftf.toString()); routestrings.add(routeftt.toString()); routestrings.add(routetff.toString()); routestrings.add(routetft.toString()); routestrings.add(routettf.toString()); routestrings.add(routettt.toString()); Assert.assertEquals("some flagged route.toString() are equal", 8, routestrings.size()); } @Test public void testInvalidArguments() { final HttpHost[] chain1 = { PROXY1 }; // for reference: this one should succeed final HttpRoute route = new HttpRoute(TARGET1, null, chain1, false, TunnelType.TUNNELLED, LayerType.PLAIN); Assert.assertNotNull(route); try { new HttpRoute(null, null, chain1, false, TunnelType.TUNNELLED, LayerType.PLAIN); Assert.fail("missing target not detected"); } catch (final IllegalArgumentException iax) { // expected } try { new HttpRoute(TARGET1, null, (HttpHost[]) null, false, TunnelType.TUNNELLED, LayerType.PLAIN); Assert.fail("missing proxy for tunnel not detected"); } catch (final IllegalArgumentException iax) { // expected } } @Test public void testNullEnums() { // tests the default values for the enum parameters // also covers the accessors for the enum attributes final HttpRoute route = new HttpRoute(TARGET1, null, PROXY1, false, null, null); // here are defaults Assert.assertFalse("default tunnelling", route.isTunnelled()); Assert.assertEquals("untunnelled", TunnelType.PLAIN, route.getTunnelType()); Assert.assertFalse("default layering", route.isLayered()); Assert.assertEquals("unlayered", LayerType.PLAIN, route.getLayerType()); } @Test public void testEqualsHashcodeClone() throws CloneNotSupportedException { final HttpHost[] chain0 = { }; final HttpHost[] chain1 = { PROXY1 }; final HttpHost[] chain3 = { PROXY1, PROXY2, PROXY3 }; final HttpHost[] chain4 = { PROXY1, PROXY3, PROXY2 }; // create some identical routes final HttpRoute route1a = new HttpRoute(TARGET1, LOCAL41, chain3, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route1b = new HttpRoute(TARGET1, LOCAL41, chain3, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route1c = (HttpRoute) route1a.clone(); Assert.assertEquals("1a 1a", route1a, route1a); Assert.assertEquals("1a 1b", route1a, route1b); Assert.assertEquals("1a 1c", route1a, route1c); Assert.assertEquals("hashcode 1a", route1a.hashCode(), route1a.hashCode()); Assert.assertEquals("hashcode 1b", route1a.hashCode(), route1b.hashCode()); Assert.assertEquals("hashcode 1c", route1a.hashCode(), route1c.hashCode()); Assert.assertEquals("toString 1a", route1a.toString(), route1a.toString()); Assert.assertEquals("toString 1b", route1a.toString(), route1b.toString()); Assert.assertEquals("toString 1c", route1a.toString(), route1c.toString()); // now create some differing routes final HttpRoute route2a = new HttpRoute(TARGET2, LOCAL41, chain3, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route2b = new HttpRoute(TARGET1, LOCAL42, chain3, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route2c = new HttpRoute(TARGET1, LOCAL61, chain3, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route2d = new HttpRoute(TARGET1, null, chain3, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route2e = new HttpRoute(TARGET1, LOCAL41, (HttpHost[]) null, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route2f = new HttpRoute(TARGET1, LOCAL41, chain0, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route2g = new HttpRoute(TARGET1, LOCAL41, chain1, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route2h = new HttpRoute(TARGET1, LOCAL41, chain4, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route2i = new HttpRoute(TARGET1, LOCAL41, chain3, true, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route2j = new HttpRoute(TARGET1, LOCAL41, chain3, false, TunnelType.TUNNELLED, LayerType.PLAIN); final HttpRoute route2k = new HttpRoute(TARGET1, LOCAL41, chain3, false, TunnelType.PLAIN, LayerType.LAYERED); // check a special case first: 2f should be the same as 2e Assert.assertEquals("2e 2f", route2e, route2f); Assert.assertEquals("hashcode 2e 2f", route2e.hashCode(), route2f.hashCode()); Assert.assertEquals("toString 2e 2f", route2e.toString(), route2f.toString()); Assert.assertFalse("1a 2a", route1a.equals(route2a)); Assert.assertFalse("1a 2b", route1a.equals(route2b)); Assert.assertFalse("1a 2c", route1a.equals(route2c)); Assert.assertFalse("1a 2d", route1a.equals(route2d)); Assert.assertFalse("1a 2e", route1a.equals(route2e)); Assert.assertFalse("1a 2f", route1a.equals(route2f)); Assert.assertFalse("1a 2g", route1a.equals(route2g)); Assert.assertFalse("1a 2h", route1a.equals(route2h)); Assert.assertFalse("1a 2i", route1a.equals(route2i)); Assert.assertFalse("1a 2j", route1a.equals(route2j)); Assert.assertFalse("1a 2k", route1a.equals(route2k)); // repeat the checks in the other direction // there could be problems with detecting null attributes Assert.assertFalse("2a 1a", route2a.equals(route1a)); Assert.assertFalse("2b 1a", route2b.equals(route1a)); Assert.assertFalse("2c 1a", route2c.equals(route1a)); Assert.assertFalse("2d 1a", route2d.equals(route1a)); Assert.assertFalse("2e 1a", route2e.equals(route1a)); Assert.assertFalse("2f 1a", route2f.equals(route1a)); Assert.assertFalse("2g 1a", route2g.equals(route1a)); Assert.assertFalse("2h 1a", route2h.equals(route1a)); Assert.assertFalse("2i 1a", route2i.equals(route1a)); Assert.assertFalse("2j 1a", route2j.equals(route1a)); Assert.assertFalse("2k 1a", route2k.equals(route1a)); // don't check hashCode, it's not guaranteed to be different Assert.assertFalse("toString 1a 2a", route1a.toString().equals(route2a.toString())); Assert.assertFalse("toString 1a 2b", route1a.toString().equals(route2b.toString())); Assert.assertFalse("toString 1a 2c", route1a.toString().equals(route2c.toString())); Assert.assertFalse("toString 1a 2d", route1a.toString().equals(route2d.toString())); Assert.assertFalse("toString 1a 2e", route1a.toString().equals(route2e.toString())); Assert.assertFalse("toString 1a 2f", route1a.toString().equals(route2f.toString())); Assert.assertFalse("toString 1a 2g", route1a.toString().equals(route2g.toString())); Assert.assertFalse("toString 1a 2h", route1a.toString().equals(route2h.toString())); Assert.assertFalse("toString 1a 2i", route1a.toString().equals(route2i.toString())); Assert.assertFalse("toString 1a 2j", route1a.toString().equals(route2j.toString())); Assert.assertFalse("toString 1a 2k", route1a.toString().equals(route2k.toString())); // now check that all of the routes are different from eachother // except for those that aren't :-) final Set routes = new HashSet(); routes.add(route1a); routes.add(route2a); routes.add(route2b); routes.add(route2c); routes.add(route2d); routes.add(route2e); //routes.add(route2f); // 2f is the same as 2e routes.add(route2g); routes.add(route2h); routes.add(route2i); routes.add(route2j); routes.add(route2k); Assert.assertEquals("some routes are equal", 11, routes.size()); // and a run of cloning over the set final Iterator iter = routes.iterator(); while (iter.hasNext()) { final HttpRoute origin = iter.next(); final HttpRoute cloned = (HttpRoute) origin.clone(); Assert.assertEquals("clone of " + origin, origin, cloned); Assert.assertTrue("clone of " + origin, routes.contains(cloned)); } // and don't forget toString final Set routestrings = new HashSet(); routestrings.add(route1a.toString()); routestrings.add(route2a.toString()); routestrings.add(route2b.toString()); routestrings.add(route2c.toString()); routestrings.add(route2d.toString()); routestrings.add(route2e.toString()); //routestrings.add(route2f.toString()); // 2f is the same as 2e routestrings.add(route2g.toString()); routestrings.add(route2h.toString()); routestrings.add(route2i.toString()); routestrings.add(route2j.toString()); routestrings.add(route2k.toString()); Assert.assertEquals("some route.toString() are equal", 11, routestrings.size()); // finally, compare with nonsense Assert.assertFalse("route equals null", route1a.equals(null)); Assert.assertFalse("route equals string", route1a.equals("route1a")); } @Test public void testHopping() { // test getHopCount() and getHopTarget() with different proxy chains HttpHost[] proxies = null; HttpRoute route = new HttpRoute(TARGET1, null, proxies, true, TunnelType.PLAIN, LayerType.PLAIN); Assert.assertEquals("A: hop count", 1, route.getHopCount()); Assert.assertEquals("A: hop 0", TARGET1, route.getHopTarget(0)); try { final HttpHost beyond = route.getHopTarget(1); Assert.fail("A: hop 1 is " + beyond); } catch (final IllegalArgumentException iax) { // expected } try { final HttpHost before = route.getHopTarget(-1); Assert.fail("A: hop -1 is " + before); } catch (final IllegalArgumentException iax) { // expected } proxies = new HttpHost[]{ PROXY3 }; route = new HttpRoute(TARGET1, LOCAL62, proxies, false, TunnelType.TUNNELLED, LayerType.PLAIN); Assert.assertEquals("B: hop count", 2, route.getHopCount()); Assert.assertEquals("B: hop 0", PROXY3, route.getHopTarget(0)); Assert.assertEquals("B: hop 1", TARGET1, route.getHopTarget(1)); try { final HttpHost beyond = route.getHopTarget(2); Assert.fail("B: hop 2 is " + beyond); } catch (final IllegalArgumentException iax) { // expected } try { final HttpHost before = route.getHopTarget(-2); Assert.fail("B: hop -2 is " + before); } catch (final IllegalArgumentException iax) { // expected } proxies = new HttpHost[]{ PROXY3, PROXY1, PROXY2 }; route = new HttpRoute(TARGET1, LOCAL42, proxies, false, TunnelType.PLAIN, LayerType.LAYERED); Assert.assertEquals("C: hop count", 4, route.getHopCount()); Assert.assertEquals("C: hop 0", PROXY3 , route.getHopTarget(0)); Assert.assertEquals("C: hop 1", PROXY1 , route.getHopTarget(1)); Assert.assertEquals("C: hop 2", PROXY2 , route.getHopTarget(2)); Assert.assertEquals("C: hop 3", TARGET1, route.getHopTarget(3)); try { final HttpHost beyond = route.getHopTarget(4); Assert.fail("C: hop 4 is " + beyond); } catch (final IllegalArgumentException iax) { // expected } try { final HttpHost before = route.getHopTarget(Integer.MIN_VALUE); Assert.fail("C: hop - is " + before); } catch (final IllegalArgumentException iax) { // expected } } @Test public void testCstr1() { final HttpRoute route = new HttpRoute(TARGET2); final HttpRoute should = new HttpRoute (TARGET2, null, (HttpHost[]) null, false, TunnelType.PLAIN, LayerType.PLAIN); Assert.assertEquals("bad convenience route", route, should); } @Test public void testCstr3() { // test convenience constructor with 3 arguments HttpRoute route = new HttpRoute(TARGET2, LOCAL61, false); HttpRoute should = new HttpRoute (TARGET2, LOCAL61, (HttpHost[]) null, false, TunnelType.PLAIN, LayerType.PLAIN); Assert.assertEquals("bad convenience route 3/insecure", route, should); route = new HttpRoute(TARGET2, null, true); should = new HttpRoute(TARGET2, null, (HttpHost[]) null, true, TunnelType.PLAIN, LayerType.PLAIN); Assert.assertEquals("bad convenience route 3/secure", route, should); } @Test public void testCstr4() { // test convenience constructor with 4 arguments HttpRoute route = new HttpRoute(TARGET2, null, PROXY2, false); HttpRoute should = new HttpRoute (TARGET2, null, new HttpHost[]{ PROXY2 }, false, TunnelType.PLAIN, LayerType.PLAIN); Assert.assertEquals("bad convenience route 4/insecure", route, should); route = new HttpRoute(TARGET2, LOCAL42, PROXY1, true); should = new HttpRoute (TARGET2, LOCAL42, new HttpHost[]{ PROXY1 }, true, TunnelType.TUNNELLED, LayerType.LAYERED); Assert.assertEquals("bad convenience route 4/secure", route, should); // this constructor REQUIRES a proxy to be specified try { new HttpRoute(TARGET1, LOCAL61, null, false); Assert.fail("missing proxy not detected"); } catch (final IllegalArgumentException iax) { // expected } } @Test public void testCstr6() { // test convenience constructor with 6 arguments HttpRoute route = new HttpRoute (TARGET2, null, PROXY2, true, TunnelType.TUNNELLED, LayerType.PLAIN); HttpRoute should = new HttpRoute (TARGET2, null, new HttpHost[]{ PROXY2 }, true, TunnelType.TUNNELLED, LayerType.PLAIN); Assert.assertEquals("bad convenience route 6/proxied", route, should); route = new HttpRoute (TARGET2, null, (HttpHost) null, true, TunnelType.PLAIN, LayerType.LAYERED); should = new HttpRoute (TARGET2, null, (HttpHost[]) null, true, TunnelType.PLAIN, LayerType.LAYERED); Assert.assertEquals("bad convenience route 6/direct", route, should); // handling of null vs. empty chain is checked in the equals tests } @Test public void testImmutable() throws CloneNotSupportedException { final HttpHost[] proxies = new HttpHost[]{ PROXY1, PROXY2, PROXY3 }; final HttpRoute route1 = new HttpRoute(TARGET1, null, proxies, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route2 = (HttpRoute) route1.clone(); final HttpRoute route3 = new HttpRoute(TARGET1, null, proxies.clone(), false, TunnelType.PLAIN, LayerType.PLAIN); // modify the array that was passed to the constructor of route1 proxies[1] = PROXY3; proxies[2] = PROXY2; Assert.assertEquals("route differs from clone", route2, route1); Assert.assertEquals("route was modified", route3, route1); } } ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/routing/TestRouteDirector.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/routing/TestRouteDirector.0100644 0000000 0000000 00000046421 12301751653 032536 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.routing; import java.net.InetAddress; import org.apache.http.HttpHost; import org.apache.http.conn.routing.RouteInfo.LayerType; import org.apache.http.conn.routing.RouteInfo.TunnelType; import org.junit.Assert; import org.junit.Test; /** * Tests for {@link BasicRouteDirector}. */ public class TestRouteDirector { // a selection of constants for generating routes public final static HttpHost TARGET1 = new HttpHost("target1.test.invalid"); public final static HttpHost TARGET2 = new HttpHost("target2.test.invalid", 8080); // It is not necessary to have extra targets for https. // The 'layered' and 'secure' flags are specified explicitly // for routes, they will not be determined from the scheme. public final static HttpHost PROXY1 = new HttpHost("proxy1.test.invalid"); public final static HttpHost PROXY2 = new HttpHost("proxy2.test.invalid", 1080); public final static HttpHost PROXY3 = new HttpHost("proxy3.test.invalid", 88); public final static InetAddress LOCAL41; public final static InetAddress LOCAL42; public final static InetAddress LOCAL61; public final static InetAddress LOCAL62; // need static initializer to deal with exceptions static { try { LOCAL41 = InetAddress.getByAddress(new byte[]{ 127, 0, 0, 1 }); LOCAL42 = InetAddress.getByAddress(new byte[]{ 127, 0, 0, 2 }); LOCAL61 = InetAddress.getByAddress(new byte[]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }); LOCAL62 = InetAddress.getByAddress(new byte[]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }); } catch (final Exception x) { throw new ExceptionInInitializerError(x); } } @Test(expected=IllegalArgumentException.class) public void testIllegal() { final HttpRouteDirector rowdy = new BasicRouteDirector(); final HttpRoute route = new HttpRoute(TARGET1); rowdy.nextStep(null, route); } @Test public void testDirect() { final HttpRouteDirector rowdy = new BasicRouteDirector(); final HttpRoute route1 = new HttpRoute(TARGET1); final HttpRoute route2 = new HttpRoute(TARGET2); final HttpRoute route1p1 = new HttpRoute(TARGET1, null, PROXY1, false); int step = rowdy.nextStep(route1, null); Assert.assertEquals("wrong step to route1", HttpRouteDirector.CONNECT_TARGET, step); step = rowdy.nextStep(route2, null); Assert.assertEquals("wrong step to route2", HttpRouteDirector.CONNECT_TARGET, step); step = rowdy.nextStep(route1, route1); Assert.assertEquals("complete route1 not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route2, route2); Assert.assertEquals("complete route2 not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1, route2); Assert.assertEquals("unreachable target not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1, route1p1); Assert.assertEquals("invalid proxy not detected", HttpRouteDirector.UNREACHABLE, step); } @Test public void testProxy() { final HttpRouteDirector rowdy = new BasicRouteDirector(); final HttpRoute route1p1 = new HttpRoute(TARGET1, null, PROXY1, false); final HttpRoute route1p2 = new HttpRoute(TARGET1, null, PROXY2, false); final HttpRoute route2p1 = new HttpRoute(TARGET2, null, PROXY1, false); final HttpRoute route0 = new HttpRoute(PROXY1); final HttpRoute route1 = new HttpRoute(TARGET1); int step = rowdy.nextStep(route1p1, null); Assert.assertEquals("wrong step to route1p1", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1p2, null); Assert.assertEquals("wrong step to route1p2", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1p1, route1p1); Assert.assertEquals("complete route1p1 not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1p2, route1p2); Assert.assertEquals("complete route1p2 not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route2p1, route2p1); Assert.assertEquals("complete route2p1 not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1p1, route1p2); Assert.assertEquals("unreachable route1p1 via route1p2 not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1p1, route2p1); Assert.assertEquals("unreachable route1p1 via route2p1 not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1p1, route0); Assert.assertEquals("unreachable route1p1 via route0 not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1p1, route1); Assert.assertEquals("unreachable route1p1 via route1 not detected", HttpRouteDirector.UNREACHABLE, step); } @Test public void testProxyChain() { final HttpHost[] chainA = { PROXY1 }; final HttpHost[] chainB = { PROXY1, PROXY2 }; final HttpHost[] chainC = { PROXY2, PROXY1 }; final HttpRouteDirector rowdy = new BasicRouteDirector(); final HttpRoute route1cA = new HttpRoute(TARGET1, null, chainA, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route1cB = new HttpRoute(TARGET1, null, chainB, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route1cC = new HttpRoute(TARGET1, null, chainC, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route1cD = new HttpRoute(TARGET1, null, chainC, false, TunnelType.PLAIN, LayerType.PLAIN); int step = rowdy.nextStep(route1cA, null); Assert.assertEquals("wrong step to route1cA", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1cB, null); Assert.assertEquals("wrong step to route1cB", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1cC, null); Assert.assertEquals("wrong step to route1cC", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1cD, null); Assert.assertEquals("wrong step to route1cD", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1cB, route1cA); Assert.assertEquals("wrong step to route 1cB from 1cA", HttpRouteDirector.TUNNEL_PROXY, step); step = rowdy.nextStep(route1cB, route1cB); Assert.assertEquals("complete route 1cB not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1cB, route1cC); Assert.assertEquals("unreachable route 1cB from 1cC not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1cB, route1cD); Assert.assertEquals("unreachable route 1cB from 1cD not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1cA, route1cB); Assert.assertEquals("unreachable route 1cA from 1cB not detected", HttpRouteDirector.UNREACHABLE, step); } @Test public void testLocalDirect() { final HttpRouteDirector rowdy = new BasicRouteDirector(); final HttpRoute route1l41 = new HttpRoute(TARGET1, LOCAL41, false); final HttpRoute route1l42 = new HttpRoute(TARGET1, LOCAL42, false); final HttpRoute route1l61 = new HttpRoute(TARGET1, LOCAL61, false); final HttpRoute route1l00 = new HttpRoute(TARGET1, null, false); int step = rowdy.nextStep(route1l41, null); Assert.assertEquals("wrong step to route1l41", HttpRouteDirector.CONNECT_TARGET, step); step = rowdy.nextStep(route1l42, null); Assert.assertEquals("wrong step to route1l42", HttpRouteDirector.CONNECT_TARGET, step); step = rowdy.nextStep(route1l61, null); Assert.assertEquals("wrong step to route1l61", HttpRouteDirector.CONNECT_TARGET, step); step = rowdy.nextStep(route1l00, null); Assert.assertEquals("wrong step to route1l00", HttpRouteDirector.CONNECT_TARGET, step); step = rowdy.nextStep(route1l41, route1l41); Assert.assertEquals("complete route1l41 not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1l42, route1l42); Assert.assertEquals("complete route1l42 not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1l61, route1l61); Assert.assertEquals("complete route1l61 not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1l00, route1l00); Assert.assertEquals("complete route1l00 not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1l41, route1l42); Assert.assertEquals("unreachable route1l41 via route1l42 not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1l41, route1l61); Assert.assertEquals("unreachable route1l41 via route1l61 not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1l41, route1l00); Assert.assertEquals("unreachable route1l41 via route1l00 not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1l00, route1l41); Assert.assertEquals("complete route1l00 as route1l41 not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1l00, route1l42); Assert.assertEquals("complete route1l00 as route1l42 not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1l00, route1l61); Assert.assertEquals("complete route1l00 as route1l61 not detected", HttpRouteDirector.COMPLETE, step); } @Test public void testDirectSecure() { final HttpRouteDirector rowdy = new BasicRouteDirector(); final HttpRoute route1u = new HttpRoute(TARGET1, null, false); final HttpRoute route1s = new HttpRoute(TARGET1, null, true); final HttpRoute route1p1u = new HttpRoute(TARGET1, null, PROXY1, false); final HttpRoute route1p1s = new HttpRoute(TARGET1, null, PROXY1, true); int step = rowdy.nextStep(route1u, null); Assert.assertEquals("wrong step to route1u", HttpRouteDirector.CONNECT_TARGET, step); step = rowdy.nextStep(route1s, null); Assert.assertEquals("wrong step to route1s", HttpRouteDirector.CONNECT_TARGET, step); // unrequested security is currently not tolerated step = rowdy.nextStep(route1u, route1s); Assert.assertEquals("unreachable route 1u from 1s not detected", HttpRouteDirector.UNREACHABLE, step); // secure layering of direct connections is currently not supported step = rowdy.nextStep(route1s, route1u); Assert.assertEquals("unreachable route 1s from 1u not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1s, route1p1u); Assert.assertEquals("unreachable route 1s from 1p1u not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1s, route1p1s); Assert.assertEquals("unreachable route 1s from 1p1s not detected", HttpRouteDirector.UNREACHABLE, step); } @Test public void testProxyTLS() { final HttpRouteDirector rowdy = new BasicRouteDirector(); final HttpRoute route1 = new HttpRoute (TARGET1, null, PROXY1, false, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route1t = new HttpRoute (TARGET1, null, PROXY1, false, TunnelType.TUNNELLED, LayerType.PLAIN); final HttpRoute route1tl = new HttpRoute (TARGET1, null, PROXY1, false, TunnelType.TUNNELLED, LayerType.LAYERED); final HttpRoute route1s = new HttpRoute (TARGET1, null, PROXY1, true, TunnelType.PLAIN, LayerType.PLAIN); final HttpRoute route1ts = new HttpRoute (TARGET1, null, PROXY1, true, TunnelType.TUNNELLED, LayerType.PLAIN); final HttpRoute route1tls = new HttpRoute (TARGET1, null, PROXY1, true, TunnelType.TUNNELLED, LayerType.LAYERED); // we don't consider a route that is layered but not tunnelled int step = rowdy.nextStep(route1, null); Assert.assertEquals("wrong step to route1", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1t, null); Assert.assertEquals("wrong step to route1t", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1tl, null); Assert.assertEquals("wrong step to route1tl", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1s, null); Assert.assertEquals("wrong step to route1s", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1ts, null); Assert.assertEquals("wrong step to route1ts", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1tls, null); Assert.assertEquals("wrong step to route1tls", HttpRouteDirector.CONNECT_PROXY, step); step = rowdy.nextStep(route1, route1); Assert.assertEquals("complete route1 not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1t, route1t); Assert.assertEquals("complete route1t not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1tl, route1tl); Assert.assertEquals("complete route1tl not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1s, route1s); Assert.assertEquals("complete route1s not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1ts, route1ts); Assert.assertEquals("complete route1ts not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1tls, route1tls); Assert.assertEquals("complete route1tls not detected", HttpRouteDirector.COMPLETE, step); step = rowdy.nextStep(route1, route1t); Assert.assertEquals("unreachable route1 from 1t not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1, route1tl); Assert.assertEquals("unreachable route1 from 1tl not detected", HttpRouteDirector.UNREACHABLE, step); // unrequested security is currently not tolerated step = rowdy.nextStep(route1, route1s); Assert.assertEquals("unreachable route1 from 1s not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1, route1ts); Assert.assertEquals("unreachable route1 from 1ts not detected", HttpRouteDirector.UNREACHABLE, step); step = rowdy.nextStep(route1, route1tls); Assert.assertEquals("unreachable route1 from 1tls not detected", HttpRouteDirector.UNREACHABLE, step); // securing requires layering step = rowdy.nextStep(route1s, route1); Assert.assertEquals("unreachable route1s from 1 not detected", HttpRouteDirector.UNREACHABLE, step); // securing requires layering, and multiple layers are not supported step = rowdy.nextStep(route1tls, route1tl); Assert.assertEquals("unreachable route1tls from 1tl not detected", HttpRouteDirector.UNREACHABLE, step); // cases where tunnelling to the target is required step = rowdy.nextStep(route1t, route1); Assert.assertEquals("wrong step to route1t from 1", HttpRouteDirector.TUNNEL_TARGET, step); step = rowdy.nextStep(route1tl, route1); Assert.assertEquals("wrong step to route1tl from 1", HttpRouteDirector.TUNNEL_TARGET, step); step = rowdy.nextStep(route1tls, route1); Assert.assertEquals("wrong step to route1tls from 1", HttpRouteDirector.TUNNEL_TARGET, step); // cases where layering on the tunnel is required step = rowdy.nextStep(route1tl, route1t); Assert.assertEquals("wrong step to route1tl from 1t", HttpRouteDirector.LAYER_PROTOCOL, step); step = rowdy.nextStep(route1tl, route1ts); Assert.assertEquals("wrong step to route1tl from 1ts", HttpRouteDirector.LAYER_PROTOCOL, step); step = rowdy.nextStep(route1tls, route1t); Assert.assertEquals("wrong step to route1tls from 1t", HttpRouteDirector.LAYER_PROTOCOL, step); step = rowdy.nextStep(route1tls, route1ts); Assert.assertEquals("wrong step to route1tls from 1ts", HttpRouteDirector.LAYER_PROTOCOL, step); // There are some odd cases left over, like having a secure tunnel // that becomes unsecure by layering, or a secure connection to a // proxy that becomes unsecure by tunnelling to another proxy. } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/routing/TestRouteTracker.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/routing/TestRouteTracker.j0100644 0000000 0000000 00000066104 12301751653 032530 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.routing; import java.net.InetAddress; import java.util.HashSet; import java.util.Set; import org.apache.http.HttpHost; import org.apache.http.conn.routing.RouteInfo.LayerType; import org.apache.http.conn.routing.RouteInfo.TunnelType; import org.junit.Assert; import org.junit.Test; /** * Tests for {@link RouteTracker}. */ public class TestRouteTracker { // a selection of constants for generating routes public final static HttpHost TARGET1 = new HttpHost("target1.test.invalid"); public final static HttpHost TARGET2 = new HttpHost("target2.test.invalid", 8080); // It is not necessary to have extra targets for https. // The 'layered' and 'secure' flags are specified explicitly // for routes, they will not be determined from the scheme. public final static HttpHost PROXY1 = new HttpHost("proxy1.test.invalid"); public final static HttpHost PROXY2 = new HttpHost("proxy2.test.invalid", 1080); public final static HttpHost PROXY3 = new HttpHost("proxy3.test.invalid", 88); public final static InetAddress LOCAL41; public final static InetAddress LOCAL42; public final static InetAddress LOCAL61; public final static InetAddress LOCAL62; // need static initializer to deal with exceptions static { try { LOCAL41 = InetAddress.getByAddress(new byte[]{ 127, 0, 0, 1 }); LOCAL42 = InetAddress.getByAddress(new byte[]{ 127, 0, 0, 2 }); LOCAL61 = InetAddress.getByAddress(new byte[]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }); LOCAL62 = InetAddress.getByAddress(new byte[]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }); } catch (final Exception x) { throw new ExceptionInInitializerError(x); } } @Test public void testCstrTargetLocal() { RouteTracker rt = new RouteTracker(TARGET1, null); Assert.assertEquals("wrong target (target,null)", TARGET1, rt.getTargetHost()); Assert.assertEquals("wrong local address (target,null)", null, rt.getLocalAddress()); Assert.assertEquals("wrong hop count (target,null)", 0, rt.getHopCount()); Assert.assertEquals("wrong proxy (target,null)", null, rt.getProxyHost()); Assert.assertEquals("wrong route (target,null)", null, rt.toRoute()); checkCTLS(rt, false, false, false, false); rt = new RouteTracker(TARGET2, LOCAL61); Assert.assertEquals("wrong target (target,local)", TARGET2, rt.getTargetHost()); Assert.assertEquals("wrong local address (target,local)", LOCAL61, rt.getLocalAddress()); Assert.assertEquals("wrong hop count (target,local)", 0, rt.getHopCount()); Assert.assertEquals("wrong proxy (target,local)", null, rt.getProxyHost()); Assert.assertEquals("wrong route (target,local)", null, rt.toRoute()); checkCTLS(rt, false, false, false, false); rt = null; try { new RouteTracker(null, LOCAL41); Assert.fail("null target not detected"); } catch (final IllegalArgumentException iax) { // expected } } @Test public void testCstrRoute() { HttpRoute r = new HttpRoute(TARGET1); RouteTracker rt = new RouteTracker(r); Assert.assertEquals("wrong target (r1)", TARGET1, rt.getTargetHost()); Assert.assertEquals("wrong local address (r1)", null, rt.getLocalAddress()); Assert.assertEquals("wrong hop count (r1)", 0, rt.getHopCount()); Assert.assertEquals("wrong proxy (r1)", null, rt.getProxyHost()); Assert.assertEquals("wrong route (r1)", null, rt.toRoute()); checkCTLS(rt, false, false, false, false); r = new HttpRoute(TARGET2, LOCAL61, true); rt = new RouteTracker(r); Assert.assertEquals("wrong target (r2)", TARGET2, rt.getTargetHost()); Assert.assertEquals("wrong local address (r2)", LOCAL61, rt.getLocalAddress()); Assert.assertEquals("wrong hop count (r2)", 0, rt.getHopCount()); Assert.assertEquals("wrong proxy (r2)", null, rt.getProxyHost()); Assert.assertEquals("wrong route (r2)", null, rt.toRoute()); checkCTLS(rt, false, false, false, false); r = new HttpRoute(TARGET1, LOCAL42, PROXY3, true); rt = new RouteTracker(r); Assert.assertEquals("wrong target (r3)", TARGET1, rt.getTargetHost()); Assert.assertEquals("wrong local address (r3)", LOCAL42, rt.getLocalAddress()); Assert.assertEquals("wrong hop count (r3)", 0, rt.getHopCount()); Assert.assertEquals("wrong proxy (r3)", null, rt.getProxyHost()); Assert.assertEquals("wrong route (r3)", null, rt.toRoute()); checkCTLS(rt, false, false, false, false); rt = null; try { new RouteTracker(null); Assert.fail("null route not detected"); } catch (final NullPointerException npx) { // expected } } @Test public void testIllegalArgs() { final RouteTracker rt = new RouteTracker(TARGET2, null); try { rt.connectProxy(null, true); Assert.fail("missing proxy argument not detected (connect/false)"); } catch (final IllegalArgumentException iax) { // expected } try { rt.connectProxy(null, false); Assert.fail("missing proxy argument not detected (connect/true)"); } catch (final IllegalArgumentException iax) { // expected } rt.connectProxy(PROXY1, false); try { rt.tunnelProxy(null, false); Assert.fail("missing proxy argument not detected (tunnel/false)"); } catch (final IllegalArgumentException iax) { // expected } try { rt.tunnelProxy(null, true); Assert.fail("missing proxy argument not detected (tunnel/true)"); } catch (final IllegalArgumentException iax) { // expected } try { rt.getHopTarget(-1); Assert.fail("negative hop index not detected"); } catch (final IllegalArgumentException iax) { // expected } try { rt.getHopTarget(2); Assert.fail("excessive hop index not detected"); } catch (final IllegalArgumentException iax) { // expected } } @Test public void testIllegalStates() { final RouteTracker rt = new RouteTracker(TARGET1, null); try { rt.tunnelTarget(false); Assert.fail("unconnectedness not detected (tunnelTarget)"); } catch (final IllegalStateException isx) { // expected } try { rt.tunnelProxy(PROXY1, false); Assert.fail("unconnectedness not detected (tunnelProxy)"); } catch (final IllegalStateException isx) { // expected } try { rt.layerProtocol(true); Assert.fail("unconnectedness not detected (layerProtocol)"); } catch (final IllegalStateException isx) { // expected } // connect directly rt.connectTarget(false); try { rt.connectTarget(false); Assert.fail("connectedness not detected (connectTarget)"); } catch (final IllegalStateException isx) { // expected } try { rt.connectProxy(PROXY2, false); Assert.fail("connectedness not detected (connectProxy)"); } catch (final IllegalStateException isx) { // expected } try { rt.tunnelTarget(false); Assert.fail("unproxiedness not detected (tunnelTarget)"); } catch (final IllegalStateException isx) { // expected } try { rt.tunnelProxy(PROXY1, false); Assert.fail("unproxiedness not detected (tunnelProxy)"); } catch (final IllegalStateException isx) { // expected } } @Test public void testDirectRoutes() { final HttpRouteDirector rd = new BasicRouteDirector(); HttpRoute r = new HttpRoute(TARGET1, LOCAL41, false); RouteTracker rt = new RouteTracker(r); boolean complete = checkVia(rt, r, rd, 2); Assert.assertTrue("incomplete route 1", complete); r = new HttpRoute(TARGET2, LOCAL62, true); rt = new RouteTracker(r); complete = checkVia(rt, r, rd, 2); Assert.assertTrue("incomplete route 2", complete); } @Test public void testProxyRoutes() { final HttpRouteDirector rd = new BasicRouteDirector(); HttpRoute r = new HttpRoute(TARGET2, null, PROXY1, false); RouteTracker rt = new RouteTracker(r); boolean complete = checkVia(rt, r, rd, 2); Assert.assertTrue("incomplete route 1", complete); // tunnelled, but neither secure nor layered r = new HttpRoute(TARGET1, LOCAL61, PROXY3, false, TunnelType.TUNNELLED, LayerType.PLAIN); rt = new RouteTracker(r); complete = checkVia(rt, r, rd, 3); Assert.assertTrue("incomplete route 2", complete); // tunnelled, layered, but not secure r = new HttpRoute(TARGET1, LOCAL61, PROXY3, false, TunnelType.TUNNELLED, LayerType.LAYERED); rt = new RouteTracker(r); complete = checkVia(rt, r, rd, 4); Assert.assertTrue("incomplete route 3", complete); // tunnelled, layered, secure r = new HttpRoute(TARGET1, LOCAL61, PROXY3, true); rt = new RouteTracker(r); complete = checkVia(rt, r, rd, 4); Assert.assertTrue("incomplete route 4", complete); } @Test public void testProxyChainRoutes() { final HttpRouteDirector rd = new BasicRouteDirector(); HttpHost[] proxies = { PROXY1, PROXY2 }; HttpRoute r = new HttpRoute(TARGET2, LOCAL42, proxies, false, TunnelType.PLAIN, LayerType.PLAIN); RouteTracker rt = new RouteTracker(r); boolean complete = checkVia(rt, r, rd, 3); Assert.assertTrue("incomplete route 1", complete); // tunnelled, but neither secure nor layered proxies = new HttpHost[]{ PROXY3, PROXY2 }; r = new HttpRoute(TARGET1, null, proxies, false, TunnelType.TUNNELLED, LayerType.PLAIN); rt = new RouteTracker(r); complete = checkVia(rt, r, rd, 4); Assert.assertTrue("incomplete route 2", complete); // tunnelled, layered, but not secure proxies = new HttpHost[]{ PROXY3, PROXY2, PROXY1 }; r = new HttpRoute(TARGET2, LOCAL61, proxies, false, TunnelType.TUNNELLED, LayerType.LAYERED); rt = new RouteTracker(r); complete = checkVia(rt, r, rd, 6); Assert.assertTrue("incomplete route 3", complete); // tunnelled, layered, secure proxies = new HttpHost[]{ PROXY1, PROXY3 }; r = new HttpRoute(TARGET1, LOCAL61, proxies, true, TunnelType.TUNNELLED, LayerType.LAYERED); rt = new RouteTracker(r); complete = checkVia(rt, r, rd, 5); Assert.assertTrue("incomplete route 4", complete); } @Test public void testEqualsHashcodeCloneToString() throws CloneNotSupportedException { final RouteTracker rt0 = new RouteTracker(TARGET1, null); final RouteTracker rt1 = new RouteTracker(TARGET2, null); final RouteTracker rt2 = new RouteTracker(TARGET1, null); final RouteTracker rt3 = new RouteTracker(TARGET1, null); final RouteTracker rt4 = new RouteTracker(TARGET1, LOCAL41); final RouteTracker rt6 = new RouteTracker(TARGET1, LOCAL62); Assert.assertFalse("rt0", rt0.equals(null)); Assert.assertTrue("rt0", rt0.equals(rt0)); Assert.assertFalse("rt0", rt0.equals(rt0.toString())); Assert.assertFalse("rt0 == rt4", rt0.equals(rt4)); Assert.assertFalse("rt0 == rt1", rt0.equals(rt1)); // Check host takes part in equals // Check that connection takes part in equals Assert.assertTrue("rt0 != rt2", rt0.equals(rt2)); rt2.connectTarget(false); Assert.assertFalse("rt0 == rt2", rt0.equals(rt2)); Assert.assertTrue("rt0 != rt3", rt0.equals(rt3)); rt3.connectTarget(true); Assert.assertFalse("rt0 == rt3", rt0.equals(rt3)); Assert.assertFalse("rt2 == rt3", rt2.equals(rt3)); // Test secure takes part // TODO needs tests for tunnel and layered Assert.assertFalse("rt4 == rt0", rt4.equals(rt0)); Assert.assertFalse("rt0 == rt6", rt0.equals(rt6)); Assert.assertFalse("rt6 == rt0", rt6.equals(rt0)); Assert.assertFalse("rt4 == rt6", rt4.equals(rt6)); Assert.assertFalse("rt6 == rt4", rt6.equals(rt4)); // it is likely but not guaranteed that the hashcodes are different Assert.assertFalse("rt0 == rt4 (hashcode)", rt0.hashCode() == rt4.hashCode()); Assert.assertFalse("rt0 == rt6 (hashcode)", rt0.hashCode() == rt6.hashCode()); Assert.assertFalse("rt6 == rt4 (hashcode)", rt6.hashCode() == rt4.hashCode()); Assert.assertEquals("rt0 (clone)", rt0, rt0.clone()); Assert.assertEquals("rt4 (clone)", rt4, rt4.clone()); Assert.assertEquals("rt6 (clone)", rt6, rt6.clone()); // we collect (clones of) the different tracked routes along the way // rt0 -> direct connection // rt1 -> via single proxy // rt2 -> via proxy chain final Set hs = new HashSet(); // we also collect hashcodes for the different paths // since we can't guarantee what influence the HttpHost hashcodes have, // we keep separate sets here final Set hc0 = new HashSet(); final Set hc4 = new HashSet(); final Set hc6 = new HashSet(); RouteTracker rt = null; Assert.assertTrue(hs.add(rt0)); Assert.assertTrue(hs.add(rt4)); Assert.assertTrue(hs.add(rt6)); Assert.assertTrue(hc0.add(Integer.valueOf(rt0.hashCode()))); Assert.assertTrue(hc4.add(Integer.valueOf(rt4.hashCode()))); Assert.assertTrue(hc6.add(Integer.valueOf(rt6.hashCode()))); rt = (RouteTracker) rt0.clone(); rt.connectTarget(false); Assert.assertTrue(hs.add(rt)); Assert.assertTrue(hc0.add(Integer.valueOf(rt.hashCode()))); rt = (RouteTracker) rt0.clone(); rt.connectTarget(true); Assert.assertTrue(hs.add(rt)); Assert.assertTrue(hc0.add(Integer.valueOf(rt.hashCode()))); // proxy (insecure) -> tunnel (insecure) -> layer (secure) rt = (RouteTracker) rt4.clone(); rt.connectProxy(PROXY1, false); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); // this is not guaranteed to be unique... Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode()))); rt.tunnelTarget(false); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode()))); rt.layerProtocol(true); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode()))); // proxy (secure) -> tunnel (secure) -> layer (insecure) rt = (RouteTracker) rt4.clone(); rt.connectProxy(PROXY1, true); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); // this is not guaranteed to be unique... Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode()))); rt.tunnelTarget(true); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode()))); rt.layerProtocol(false); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode()))); // PROXY1/i -> PROXY2/i -> tunnel/i -> layer/s rt = (RouteTracker) rt6.clone(); rt.connectProxy(PROXY1, false); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); // this is not guaranteed to be unique... Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode()))); rt.tunnelProxy(PROXY2, false); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); // this is not guaranteed to be unique... Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode()))); rt.tunnelTarget(false); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode()))); rt.layerProtocol(true); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode()))); // PROXY1/s -> PROXY2/s -> tunnel/s -> layer/i rt = (RouteTracker) rt6.clone(); rt.connectProxy(PROXY1, true); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); // this is not guaranteed to be unique... Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode()))); rt.tunnelProxy(PROXY2, true); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); // this is not guaranteed to be unique... Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode()))); rt.tunnelTarget(true); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode()))); rt.layerProtocol(false); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode()))); // PROXY2/i -> PROXY1/i -> tunnel/i -> layer/s rt = (RouteTracker) rt6.clone(); rt.connectProxy(PROXY2, false); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); // this is not guaranteed to be unique... Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode()))); rt.tunnelProxy(PROXY1, false); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); // proxy chain sequence does not affect hashcode, so duplicate: // Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode()))); rt.tunnelTarget(false); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); // proxy chain sequence does not affect hashcode, so duplicate: // Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode()))); rt.layerProtocol(true); Assert.assertTrue(hs.add((RouteTracker) rt.clone())); // proxy chain sequence does not affect hashcode, so duplicate: // Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode()))); // check that all toString are OK and different final Set rtstrings = new HashSet(); for (final RouteTracker current: hs) { final String rts = checkToString(current); Assert.assertTrue("duplicate toString: " + rts, rtstrings.add(rts)); } } /** Helper to check the status of the four flags. */ public final static void checkCTLS(final RouteTracker rt, final boolean c, final boolean t, final boolean l, final boolean s) { final String rts = rt.toString(); Assert.assertEquals("wrong flag connected: " + rts, c, rt.isConnected()); Assert.assertEquals("wrong flag tunnelled: " + rts, t, rt.isTunnelled()); Assert.assertEquals("wrong enum tunnelled: " + rts, t ? TunnelType.TUNNELLED : TunnelType.PLAIN, rt.getTunnelType()); Assert.assertEquals("wrong flag layered: " + rts, l, rt.isLayered()); Assert.assertEquals("wrong enum layered: " + rts, l ? LayerType.LAYERED : LayerType.PLAIN, rt.getLayerType()); Assert.assertEquals("wrong flag secure: " + rts, s, rt.isSecure()); } /** * Helper to check tracking of a route. * This uses a {@link HttpRouteDirector} to fake establishing the route, * checking the intermediate steps. * * @param rt the tracker to check with * @param r the route to establish * @param rd the director to check with * @param steps the step count for this invocation * * @return true iff the route is complete */ public final static boolean checkVia(final RouteTracker rt, final HttpRoute r, final HttpRouteDirector rd, final int steps) { final String msg = r.toString() + " @ " + rt.toString(); boolean complete = false; int n = steps; while (!complete && (n > 0)) { final int action = rd.nextStep(r, rt.toRoute()); switch (action) { case HttpRouteDirector.COMPLETE: complete = true; Assert.assertEquals(r, rt.toRoute()); break; case HttpRouteDirector.CONNECT_TARGET: { final boolean sec = r.isSecure(); rt.connectTarget(sec); checkCTLS(rt, true, false, false, sec); Assert.assertEquals("wrong hop count "+msg, 1, rt.getHopCount()); Assert.assertEquals("wrong hop0 "+msg, r.getTargetHost(), rt.getHopTarget(0)); } break; case HttpRouteDirector.CONNECT_PROXY: { // we assume an insecure proxy connection final boolean sec = false; rt.connectProxy(r.getProxyHost(), sec); checkCTLS(rt, true, false, false, sec); Assert.assertEquals("wrong hop count "+msg, 2, rt.getHopCount()); Assert.assertEquals("wrong hop0 "+msg, r.getProxyHost(), rt.getHopTarget(0)); Assert.assertEquals("wrong hop1 "+msg, r.getTargetHost(), rt.getHopTarget(1)); } break; case HttpRouteDirector.TUNNEL_TARGET: { final int hops = rt.getHopCount(); // we assume an insecure tunnel final boolean sec = false; rt.tunnelTarget(sec); checkCTLS(rt, true, true, false, sec); Assert.assertEquals("wrong hop count "+msg, hops, rt.getHopCount()); Assert.assertEquals("wrong hop0 "+msg, r.getProxyHost(), rt.getHopTarget(0)); Assert.assertEquals("wrong hopN "+msg, r.getTargetHost(), rt.getHopTarget(hops-1)); } break; case HttpRouteDirector.TUNNEL_PROXY: { final int hops = rt.getHopCount(); // before tunnelling // we assume an insecure tunnel final boolean sec = false; final HttpHost pxy = r.getHopTarget(hops-1); rt.tunnelProxy(pxy, sec); // Since we're tunnelling to a proxy and not the target, // the 'tunelling' flag is false: no end-to-end tunnel. checkCTLS(rt, true, false, false, sec); Assert.assertEquals("wrong hop count "+msg, hops+1, rt.getHopCount()); Assert.assertEquals("wrong hop0 "+msg, r.getProxyHost(), rt.getHopTarget(0)); Assert.assertEquals("wrong hop"+hops+" "+msg, pxy, rt.getHopTarget(hops-1)); Assert.assertEquals("wrong hopN "+msg, r.getTargetHost(), rt.getHopTarget(hops)); } break; case HttpRouteDirector.LAYER_PROTOCOL: { final int hops = rt.getHopCount(); final boolean tun = rt.isTunnelled(); final boolean sec = r.isSecure(); rt.layerProtocol(sec); checkCTLS(rt, true, tun, true, sec); Assert.assertEquals("wrong hop count "+msg, hops, rt.getHopCount()); Assert.assertEquals("wrong proxy "+msg, r.getProxyHost(), rt.getProxyHost()); Assert.assertEquals("wrong target "+msg, r.getTargetHost(), rt.getTargetHost()); } break; // UNREACHABLE default: Assert.fail("unexpected action " + action + " from director, "+msg); break; } // switch n--; } return complete; } // checkVia /** * Checks the output of toString. * * @param rt the tracker for which to check the output * * @return the result of rt.toString() */ public final static String checkToString(final RouteTracker rt) { if (rt == null) { return null; } final String rts = rt.toString(); if (rt.getLocalAddress() != null) { final String las = rt.getLocalAddress().toString(); Assert.assertFalse("no local address in toString(): " + rts, rts.indexOf(las) < 0); } for (int i=0; i. * */ package org.apache.http.conn.ssl; /** * Some X509 certificates to test against. *

* Note: some of these certificates have Japanese Kanji in the "subjectAlt" * field (UTF8). Not sure how realistic that is since international characters * in DNS names usually get translated into ASCII using "xn--" style DNS * entries. "xn--i8s592g.co.jp" is what FireFox actually uses when trying to * find 花子.co.jp. So would the CN in the certificate contain * "xn--i8s592g.co.jp" in ASCII, or "花子.co.jp" in UTF8? (Both?) * * @since 11-Dec-2006 */ public class CertificatesToPlayWith { /** * CN=foo.com */ public final static byte[] X509_FOO = ( "-----BEGIN CERTIFICATE-----\n" + "MIIERjCCAy6gAwIBAgIJAIz+EYMBU6aQMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD\n" + "VQQGEwJDQTELMAkGA1UECBMCQkMxEjAQBgNVBAcTCVZhbmNvdXZlcjEWMBQGA1UE\n" + "ChMNd3d3LmN1Y2JjLmNvbTEUMBIGA1UECxQLY29tbW9uc19zc2wxHTAbBgNVBAMU\n" + "FGRlbW9faW50ZXJtZWRpYXRlX2NhMSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZp\n" + "ZXNAZ21haWwuY29tMB4XDTA2MTIxMTE1MzE0MVoXDTI4MTEwNTE1MzE0MVowgaQx\n" + "CzAJBgNVBAYTAlVTMREwDwYDVQQIEwhNYXJ5bGFuZDEUMBIGA1UEBxMLRm9yZXN0\n" + "IEhpbGwxFzAVBgNVBAoTDmh0dHBjb21wb25lbnRzMRowGAYDVQQLExF0ZXN0IGNl\n" + "cnRpZmljYXRlczEQMA4GA1UEAxMHZm9vLmNvbTElMCMGCSqGSIb3DQEJARYWanVs\n" + "aXVzZGF2aWVzQGdtYWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n" + "ggEBAMhjr5aCPoyp0R1iroWAfnEyBMGYWoCidH96yGPFjYLowez5aYKY1IOKTY2B\n" + "lYho4O84X244QrZTRl8kQbYtxnGh4gSCD+Z8gjZ/gMvLUlhqOb+WXPAUHMB39GRy\n" + "zerA/ZtrlUqf+lKo0uWcocxeRc771KN8cPH3nHZ0rV0Hx4ZAZy6U4xxObe4rtSVY\n" + "07hNKXAb2odnVqgzcYiDkLV8ilvEmoNWMWrp8UBqkTcpEhYhCYp3cTkgJwMSuqv8\n" + "BqnGd87xQU3FVZI4tbtkB+KzjD9zz8QCDJAfDjZHR03KNQ5mxOgXwxwKw6lGMaiV\n" + "JTxpTKqym93whYk93l3ocEe55c0CAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgB\n" + "hvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYE\n" + "FJ8Ud78/OrbKOIJCSBYs2tDLXofYMB8GA1UdIwQYMBaAFHua2o+QmU5S0qzbswNS\n" + "yoemDT4NMA0GCSqGSIb3DQEBBQUAA4IBAQC3jRmEya6sQCkmieULcvx8zz1euCk9\n" + "fSez7BEtki8+dmfMXe3K7sH0lI8f4jJR0rbSCjpmCQLYmzC3NxBKeJOW0RcjNBpO\n" + "c2JlGO9auXv2GDP4IYiXElLJ6VSqc8WvDikv0JmCCWm0Zga+bZbR/EWN5DeEtFdF\n" + "815CLpJZNcYwiYwGy/CVQ7w2TnXlG+mraZOz+owr+cL6J/ZesbdEWfjoS1+cUEhE\n" + "HwlNrAu8jlZ2UqSgskSWlhYdMTAP9CPHiUv9N7FcT58Itv/I4fKREINQYjDpvQcx\n" + "SaTYb9dr5sB4WLNglk7zxDtM80H518VvihTcP7FHL+Gn6g4j5fkI98+S\n" + "-----END CERTIFICATE-----\n").getBytes(); /** * CN=花子.co.jp */ public final static byte[] X509_HANAKO = ( "-----BEGIN CERTIFICATE-----\n" + "MIIESzCCAzOgAwIBAgIJAIz+EYMBU6aTMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD\n" + "VQQGEwJDQTELMAkGA1UECBMCQkMxEjAQBgNVBAcTCVZhbmNvdXZlcjEWMBQGA1UE\n" + "ChMNd3d3LmN1Y2JjLmNvbTEUMBIGA1UECxQLY29tbW9uc19zc2wxHTAbBgNVBAMU\n" + "FGRlbW9faW50ZXJtZWRpYXRlX2NhMSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZp\n" + "ZXNAZ21haWwuY29tMB4XDTA2MTIxMTE1NDIxNVoXDTI4MTEwNTE1NDIxNVowgakx\n" + "CzAJBgNVBAYTAlVTMREwDwYDVQQIDAhNYXJ5bGFuZDEUMBIGA1UEBwwLRm9yZXN0\n" + "IEhpbGwxFzAVBgNVBAoMDmh0dHBjb21wb25lbnRzMRowGAYDVQQLDBF0ZXN0IGNl\n" + "cnRpZmljYXRlczEVMBMGA1UEAwwM6Iqx5a2QLmNvLmpwMSUwIwYJKoZIhvcNAQkB\n" + "FhZqdWxpdXNkYXZpZXNAZ21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\n" + "MIIBCgKCAQEAyGOvloI+jKnRHWKuhYB+cTIEwZhagKJ0f3rIY8WNgujB7PlpgpjU\n" + "g4pNjYGViGjg7zhfbjhCtlNGXyRBti3GcaHiBIIP5nyCNn+Ay8tSWGo5v5Zc8BQc\n" + "wHf0ZHLN6sD9m2uVSp/6UqjS5ZyhzF5FzvvUo3xw8fecdnStXQfHhkBnLpTjHE5t\n" + "7iu1JVjTuE0pcBvah2dWqDNxiIOQtXyKW8Sag1YxaunxQGqRNykSFiEJindxOSAn\n" + "AxK6q/wGqcZ3zvFBTcVVkji1u2QH4rOMP3PPxAIMkB8ONkdHTco1DmbE6BfDHArD\n" + "qUYxqJUlPGlMqrKb3fCFiT3eXehwR7nlzQIDAQABo3sweTAJBgNVHRMEAjAAMCwG\n" + "CWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNV\n" + "HQ4EFgQUnxR3vz86tso4gkJIFiza0Mteh9gwHwYDVR0jBBgwFoAUe5raj5CZTlLS\n" + "rNuzA1LKh6YNPg0wDQYJKoZIhvcNAQEFBQADggEBALJ27i3okV/KvlDp6KMID3gd\n" + "ITl68PyItzzx+SquF8gahMh016NX73z/oVZoVUNdftla8wPUB1GwIkAnGkhQ9LHK\n" + "spBdbRiCj0gMmLCsX8SrjFvr7cYb2cK6J/fJe92l1tg/7Y4o7V/s4JBe/cy9U9w8\n" + "a0ctuDmEBCgC784JMDtT67klRfr/2LlqWhlOEq7pUFxRLbhpquaAHSOjmIcWnVpw\n" + "9BsO7qe46hidgn39hKh1WjKK2VcL/3YRsC4wUi0PBtFW6ScMCuMhgIRXSPU55Rae\n" + "UIlOdPjjr1SUNWGId1rD7W16Scpwnknn310FNxFMHVI0GTGFkNdkilNCFJcIoRA=\n" + "-----END CERTIFICATE-----\n").getBytes(); /** * CN=foo.com, subjectAlt=bar.com */ public final static byte[] X509_FOO_BAR = ( "-----BEGIN CERTIFICATE-----\n" + "MIIEXDCCA0SgAwIBAgIJAIz+EYMBU6aRMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD\n" + "VQQGEwJDQTELMAkGA1UECBMCQkMxEjAQBgNVBAcTCVZhbmNvdXZlcjEWMBQGA1UE\n" + "ChMNd3d3LmN1Y2JjLmNvbTEUMBIGA1UECxQLY29tbW9uc19zc2wxHTAbBgNVBAMU\n" + "FGRlbW9faW50ZXJtZWRpYXRlX2NhMSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZp\n" + "ZXNAZ21haWwuY29tMB4XDTA2MTIxMTE1MzYyOVoXDTI4MTEwNTE1MzYyOVowgaQx\n" + "CzAJBgNVBAYTAlVTMREwDwYDVQQIEwhNYXJ5bGFuZDEUMBIGA1UEBxMLRm9yZXN0\n" + "IEhpbGwxFzAVBgNVBAoTDmh0dHBjb21wb25lbnRzMRowGAYDVQQLExF0ZXN0IGNl\n" + "cnRpZmljYXRlczEQMA4GA1UEAxMHZm9vLmNvbTElMCMGCSqGSIb3DQEJARYWanVs\n" + "aXVzZGF2aWVzQGdtYWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n" + "ggEBAMhjr5aCPoyp0R1iroWAfnEyBMGYWoCidH96yGPFjYLowez5aYKY1IOKTY2B\n" + "lYho4O84X244QrZTRl8kQbYtxnGh4gSCD+Z8gjZ/gMvLUlhqOb+WXPAUHMB39GRy\n" + "zerA/ZtrlUqf+lKo0uWcocxeRc771KN8cPH3nHZ0rV0Hx4ZAZy6U4xxObe4rtSVY\n" + "07hNKXAb2odnVqgzcYiDkLV8ilvEmoNWMWrp8UBqkTcpEhYhCYp3cTkgJwMSuqv8\n" + "BqnGd87xQU3FVZI4tbtkB+KzjD9zz8QCDJAfDjZHR03KNQ5mxOgXwxwKw6lGMaiV\n" + "JTxpTKqym93whYk93l3ocEe55c0CAwEAAaOBkDCBjTAJBgNVHRMEAjAAMCwGCWCG\n" + "SAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4E\n" + "FgQUnxR3vz86tso4gkJIFiza0Mteh9gwHwYDVR0jBBgwFoAUe5raj5CZTlLSrNuz\n" + "A1LKh6YNPg0wEgYDVR0RBAswCYIHYmFyLmNvbTANBgkqhkiG9w0BAQUFAAOCAQEA\n" + "dQyprNZBmVnvuVWjV42sey/PTfkYShJwy1j0/jcFZR/ypZUovpiHGDO1DgL3Y3IP\n" + "zVQ26uhUsSw6G0gGRiaBDe/0LUclXZoJzXX1qpS55OadxW73brziS0sxRgGrZE/d\n" + "3g5kkio6IED47OP6wYnlmZ7EKP9cqjWwlnvHnnUcZ2SscoLNYs9rN9ccp8tuq2by\n" + "88OyhKwGjJfhOudqfTNZcDzRHx4Fzm7UsVaycVw4uDmhEHJrAsmMPpj/+XRK9/42\n" + "2xq+8bc6HojdtbCyug/fvBZvZqQXSmU8m8IVcMmWMz0ZQO8ee3QkBHMZfCy7P/kr\n" + "VbWx/uETImUu+NZg22ewEw==\n" + "-----END CERTIFICATE-----\n").getBytes(); /** * CN=foo.com, subjectAlt=bar.com, subjectAlt=花子.co.jp * (hanako.co.jp in kanji) */ public final static byte[] X509_FOO_BAR_HANAKO = ( "-----BEGIN CERTIFICATE-----\n" + "MIIEajCCA1KgAwIBAgIJAIz+EYMBU6aSMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD\n" + "VQQGEwJDQTELMAkGA1UECBMCQkMxEjAQBgNVBAcTCVZhbmNvdXZlcjEWMBQGA1UE\n" + "ChMNd3d3LmN1Y2JjLmNvbTEUMBIGA1UECxQLY29tbW9uc19zc2wxHTAbBgNVBAMU\n" + "FGRlbW9faW50ZXJtZWRpYXRlX2NhMSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZp\n" + "ZXNAZ21haWwuY29tMB4XDTA2MTIxMTE1MzgxM1oXDTI4MTEwNTE1MzgxM1owgaQx\n" + "CzAJBgNVBAYTAlVTMREwDwYDVQQIEwhNYXJ5bGFuZDEUMBIGA1UEBxMLRm9yZXN0\n" + "IEhpbGwxFzAVBgNVBAoTDmh0dHBjb21wb25lbnRzMRowGAYDVQQLExF0ZXN0IGNl\n" + "cnRpZmljYXRlczEQMA4GA1UEAxMHZm9vLmNvbTElMCMGCSqGSIb3DQEJARYWanVs\n" + "aXVzZGF2aWVzQGdtYWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n" + "ggEBAMhjr5aCPoyp0R1iroWAfnEyBMGYWoCidH96yGPFjYLowez5aYKY1IOKTY2B\n" + "lYho4O84X244QrZTRl8kQbYtxnGh4gSCD+Z8gjZ/gMvLUlhqOb+WXPAUHMB39GRy\n" + "zerA/ZtrlUqf+lKo0uWcocxeRc771KN8cPH3nHZ0rV0Hx4ZAZy6U4xxObe4rtSVY\n" + "07hNKXAb2odnVqgzcYiDkLV8ilvEmoNWMWrp8UBqkTcpEhYhCYp3cTkgJwMSuqv8\n" + "BqnGd87xQU3FVZI4tbtkB+KzjD9zz8QCDJAfDjZHR03KNQ5mxOgXwxwKw6lGMaiV\n" + "JTxpTKqym93whYk93l3ocEe55c0CAwEAAaOBnjCBmzAJBgNVHRMEAjAAMCwGCWCG\n" + "SAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4E\n" + "FgQUnxR3vz86tso4gkJIFiza0Mteh9gwHwYDVR0jBBgwFoAUe5raj5CZTlLSrNuz\n" + "A1LKh6YNPg0wIAYDVR0RBBkwF4IHYmFyLmNvbYIM6Iqx5a2QLmNvLmpwMA0GCSqG\n" + "SIb3DQEBBQUAA4IBAQBeZs7ZIYyKtdnVxVvdLgwySEPOE4pBSXii7XYv0Q9QUvG/\n" + "++gFGQh89HhABzA1mVUjH5dJTQqSLFvRfqTHqLpxSxSWqMHnvRM4cPBkIRp/XlMK\n" + "PlXadYtJLPTgpbgvulA1ickC9EwlNYWnowZ4uxnfsMghW4HskBqaV+PnQ8Zvy3L0\n" + "12c7Cg4mKKS5pb1HdRuiD2opZ+Hc77gRQLvtWNS8jQvd/iTbh6fuvTKfAOFoXw22\n" + "sWIKHYrmhCIRshUNohGXv50m2o+1w9oWmQ6Dkq7lCjfXfUB4wIbggJjpyEtbNqBt\n" + "j4MC2x5rfsLKKqToKmNE7pFEgqwe8//Aar1b+Qj+\n" + "-----END CERTIFICATE-----\n").getBytes(); /** * CN=*.foo.com */ public final static byte[] X509_WILD_FOO = ( "-----BEGIN CERTIFICATE-----\n" + "MIIESDCCAzCgAwIBAgIJAIz+EYMBU6aUMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD\n" + "VQQGEwJDQTELMAkGA1UECBMCQkMxEjAQBgNVBAcTCVZhbmNvdXZlcjEWMBQGA1UE\n" + "ChMNd3d3LmN1Y2JjLmNvbTEUMBIGA1UECxQLY29tbW9uc19zc2wxHTAbBgNVBAMU\n" + "FGRlbW9faW50ZXJtZWRpYXRlX2NhMSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZp\n" + "ZXNAZ21haWwuY29tMB4XDTA2MTIxMTE2MTU1NVoXDTI4MTEwNTE2MTU1NVowgaYx\n" + "CzAJBgNVBAYTAlVTMREwDwYDVQQIEwhNYXJ5bGFuZDEUMBIGA1UEBxMLRm9yZXN0\n" + "IEhpbGwxFzAVBgNVBAoTDmh0dHBjb21wb25lbnRzMRowGAYDVQQLExF0ZXN0IGNl\n" + "cnRpZmljYXRlczESMBAGA1UEAxQJKi5mb28uY29tMSUwIwYJKoZIhvcNAQkBFhZq\n" + "dWxpdXNkYXZpZXNAZ21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n" + "CgKCAQEAyGOvloI+jKnRHWKuhYB+cTIEwZhagKJ0f3rIY8WNgujB7PlpgpjUg4pN\n" + "jYGViGjg7zhfbjhCtlNGXyRBti3GcaHiBIIP5nyCNn+Ay8tSWGo5v5Zc8BQcwHf0\n" + "ZHLN6sD9m2uVSp/6UqjS5ZyhzF5FzvvUo3xw8fecdnStXQfHhkBnLpTjHE5t7iu1\n" + "JVjTuE0pcBvah2dWqDNxiIOQtXyKW8Sag1YxaunxQGqRNykSFiEJindxOSAnAxK6\n" + "q/wGqcZ3zvFBTcVVkji1u2QH4rOMP3PPxAIMkB8ONkdHTco1DmbE6BfDHArDqUYx\n" + "qJUlPGlMqrKb3fCFiT3eXehwR7nlzQIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCG\n" + "SAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4E\n" + "FgQUnxR3vz86tso4gkJIFiza0Mteh9gwHwYDVR0jBBgwFoAUe5raj5CZTlLSrNuz\n" + "A1LKh6YNPg0wDQYJKoZIhvcNAQEFBQADggEBAH0ipG6J561UKUfgkeW7GvYwW98B\n" + "N1ZooWX+JEEZK7+Pf/96d3Ij0rw9ACfN4bpfnCq0VUNZVSYB+GthQ2zYuz7tf/UY\n" + "A6nxVgR/IjG69BmsBl92uFO7JTNtHztuiPqBn59pt+vNx4yPvno7zmxsfI7jv0ww\n" + "yfs+0FNm7FwdsC1k47GBSOaGw38kuIVWqXSAbL4EX9GkryGGOKGNh0qvAENCdRSB\n" + "G9Z6tyMbmfRY+dLSh3a9JwoEcBUso6EWYBakLbq4nG/nvYdYvG9ehrnLVwZFL82e\n" + "l3Q/RK95bnA6cuRClGusLad0e6bjkBzx/VQ3VarDEpAkTLUGVAa0CLXtnyc=\n" + "-----END CERTIFICATE-----\n").getBytes(); /** * CN=*.co.jp */ public final static byte[] X509_WILD_CO_JP = ( "-----BEGIN CERTIFICATE-----\n" + "MIIERjCCAy6gAwIBAgIJAIz+EYMBU6aVMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD\n" + "VQQGEwJDQTELMAkGA1UECBMCQkMxEjAQBgNVBAcTCVZhbmNvdXZlcjEWMBQGA1UE\n" + "ChMNd3d3LmN1Y2JjLmNvbTEUMBIGA1UECxQLY29tbW9uc19zc2wxHTAbBgNVBAMU\n" + "FGRlbW9faW50ZXJtZWRpYXRlX2NhMSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZp\n" + "ZXNAZ21haWwuY29tMB4XDTA2MTIxMTE2MTYzMFoXDTI4MTEwNTE2MTYzMFowgaQx\n" + "CzAJBgNVBAYTAlVTMREwDwYDVQQIEwhNYXJ5bGFuZDEUMBIGA1UEBxMLRm9yZXN0\n" + "IEhpbGwxFzAVBgNVBAoTDmh0dHBjb21wb25lbnRzMRowGAYDVQQLExF0ZXN0IGNl\n" + "cnRpZmljYXRlczEQMA4GA1UEAxQHKi5jby5qcDElMCMGCSqGSIb3DQEJARYWanVs\n" + "aXVzZGF2aWVzQGdtYWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n" + "ggEBAMhjr5aCPoyp0R1iroWAfnEyBMGYWoCidH96yGPFjYLowez5aYKY1IOKTY2B\n" + "lYho4O84X244QrZTRl8kQbYtxnGh4gSCD+Z8gjZ/gMvLUlhqOb+WXPAUHMB39GRy\n" + "zerA/ZtrlUqf+lKo0uWcocxeRc771KN8cPH3nHZ0rV0Hx4ZAZy6U4xxObe4rtSVY\n" + "07hNKXAb2odnVqgzcYiDkLV8ilvEmoNWMWrp8UBqkTcpEhYhCYp3cTkgJwMSuqv8\n" + "BqnGd87xQU3FVZI4tbtkB+KzjD9zz8QCDJAfDjZHR03KNQ5mxOgXwxwKw6lGMaiV\n" + "JTxpTKqym93whYk93l3ocEe55c0CAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgB\n" + "hvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYE\n" + "FJ8Ud78/OrbKOIJCSBYs2tDLXofYMB8GA1UdIwQYMBaAFHua2o+QmU5S0qzbswNS\n" + "yoemDT4NMA0GCSqGSIb3DQEBBQUAA4IBAQA0sWglVlMx2zNGvUqFC73XtREwii53\n" + "CfMM6mtf2+f3k/d8KXhLNySrg8RRlN11zgmpPaLtbdTLrmG4UdAHHYr8O4y2BBmE\n" + "1cxNfGxxechgF8HX10QV4dkyzp6Z1cfwvCeMrT5G/V1pejago0ayXx+GPLbWlNeZ\n" + "S+Kl0m3p+QplXujtwG5fYcIpaGpiYraBLx3Tadih39QN65CnAh/zRDhLCUzKyt9l\n" + "UGPLEUDzRHMPHLnSqT1n5UU5UDRytbjJPXzF+l/+WZIsanefWLsxnkgAuZe/oMMF\n" + "EJMryEzOjg4Tfuc5qM0EXoPcQ/JlheaxZ40p2IyHqbsWV4MRYuFH4bkM\n" + "-----END CERTIFICATE-----\n").getBytes(); /** * CN=*.foo.com, subjectAlt=*.bar.com, subjectAlt=*.花子.co.jp * (*.hanako.co.jp in kanji) */ public final static byte[] X509_WILD_FOO_BAR_HANAKO = ( "-----BEGIN CERTIFICATE-----\n" + "MIIEcDCCA1igAwIBAgIJAIz+EYMBU6aWMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD\n" + "VQQGEwJDQTELMAkGA1UECBMCQkMxEjAQBgNVBAcTCVZhbmNvdXZlcjEWMBQGA1UE\n" + "ChMNd3d3LmN1Y2JjLmNvbTEUMBIGA1UECxQLY29tbW9uc19zc2wxHTAbBgNVBAMU\n" + "FGRlbW9faW50ZXJtZWRpYXRlX2NhMSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZp\n" + "ZXNAZ21haWwuY29tMB4XDTA2MTIxMTE2MTczMVoXDTI4MTEwNTE2MTczMVowgaYx\n" + "CzAJBgNVBAYTAlVTMREwDwYDVQQIEwhNYXJ5bGFuZDEUMBIGA1UEBxMLRm9yZXN0\n" + "IEhpbGwxFzAVBgNVBAoTDmh0dHBjb21wb25lbnRzMRowGAYDVQQLExF0ZXN0IGNl\n" + "cnRpZmljYXRlczESMBAGA1UEAxQJKi5mb28uY29tMSUwIwYJKoZIhvcNAQkBFhZq\n" + "dWxpdXNkYXZpZXNAZ21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n" + "CgKCAQEAyGOvloI+jKnRHWKuhYB+cTIEwZhagKJ0f3rIY8WNgujB7PlpgpjUg4pN\n" + "jYGViGjg7zhfbjhCtlNGXyRBti3GcaHiBIIP5nyCNn+Ay8tSWGo5v5Zc8BQcwHf0\n" + "ZHLN6sD9m2uVSp/6UqjS5ZyhzF5FzvvUo3xw8fecdnStXQfHhkBnLpTjHE5t7iu1\n" + "JVjTuE0pcBvah2dWqDNxiIOQtXyKW8Sag1YxaunxQGqRNykSFiEJindxOSAnAxK6\n" + "q/wGqcZ3zvFBTcVVkji1u2QH4rOMP3PPxAIMkB8ONkdHTco1DmbE6BfDHArDqUYx\n" + "qJUlPGlMqrKb3fCFiT3eXehwR7nlzQIDAQABo4GiMIGfMAkGA1UdEwQCMAAwLAYJ\n" + "YIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1Ud\n" + "DgQWBBSfFHe/Pzq2yjiCQkgWLNrQy16H2DAfBgNVHSMEGDAWgBR7mtqPkJlOUtKs\n" + "27MDUsqHpg0+DTAkBgNVHREEHTAbggkqLmJhci5jb22CDiou6Iqx5a2QLmNvLmpw\n" + "MA0GCSqGSIb3DQEBBQUAA4IBAQBobWC+D5/lx6YhX64CwZ26XLjxaE0S415ajbBq\n" + "DK7lz+Rg7zOE3GsTAMi+ldUYnhyz0wDiXB8UwKXl0SDToB2Z4GOgqQjAqoMmrP0u\n" + "WB6Y6dpkfd1qDRUzI120zPYgSdsXjHW9q2H77iV238hqIU7qCvEz+lfqqWEY504z\n" + "hYNlknbUnR525ItosEVwXFBJTkZ3Yw8gg02c19yi8TAh5Li3Ad8XQmmSJMWBV4XK\n" + "qFr0AIZKBlg6NZZFf/0dP9zcKhzSriW27bY0XfzA6GSiRDXrDjgXq6baRT6YwgIg\n" + "pgJsDbJtZfHnV1nd3M6zOtQPm1TIQpNmMMMd/DPrGcUQerD3\n" + "-----END CERTIFICATE-----\n").getBytes(); /** * CN=foo.com, CN=bar.com, CN=花子.co.jp */ public final static byte[] X509_THREE_CNS_FOO_BAR_HANAKO = ( "-----BEGIN CERTIFICATE-----\n" + "MIIEbzCCA1egAwIBAgIJAIz+EYMBU6aXMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD\n" + "VQQGEwJDQTELMAkGA1UECBMCQkMxEjAQBgNVBAcTCVZhbmNvdXZlcjEWMBQGA1UE\n" + "ChMNd3d3LmN1Y2JjLmNvbTEUMBIGA1UECxQLY29tbW9uc19zc2wxHTAbBgNVBAMU\n" + "FGRlbW9faW50ZXJtZWRpYXRlX2NhMSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZp\n" + "ZXNAZ21haWwuY29tMB4XDTA2MTIxMTE2MTk0NVoXDTI4MTEwNTE2MTk0NVowgc0x\n" + "CzAJBgNVBAYTAlVTMREwDwYDVQQIDAhNYXJ5bGFuZDEUMBIGA1UEBwwLRm9yZXN0\n" + "IEhpbGwxFzAVBgNVBAoMDmh0dHBjb21wb25lbnRzMRowGAYDVQQLDBF0ZXN0IGNl\n" + "cnRpZmljYXRlczEQMA4GA1UEAwwHZm9vLmNvbTEQMA4GA1UEAwwHYmFyLmNvbTEV\n" + "MBMGA1UEAwwM6Iqx5a2QLmNvLmpwMSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZp\n" + "ZXNAZ21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyGOv\n" + "loI+jKnRHWKuhYB+cTIEwZhagKJ0f3rIY8WNgujB7PlpgpjUg4pNjYGViGjg7zhf\n" + "bjhCtlNGXyRBti3GcaHiBIIP5nyCNn+Ay8tSWGo5v5Zc8BQcwHf0ZHLN6sD9m2uV\n" + "Sp/6UqjS5ZyhzF5FzvvUo3xw8fecdnStXQfHhkBnLpTjHE5t7iu1JVjTuE0pcBva\n" + "h2dWqDNxiIOQtXyKW8Sag1YxaunxQGqRNykSFiEJindxOSAnAxK6q/wGqcZ3zvFB\n" + "TcVVkji1u2QH4rOMP3PPxAIMkB8ONkdHTco1DmbE6BfDHArDqUYxqJUlPGlMqrKb\n" + "3fCFiT3eXehwR7nlzQIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQf\n" + "Fh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUnxR3vz86\n" + "tso4gkJIFiza0Mteh9gwHwYDVR0jBBgwFoAUe5raj5CZTlLSrNuzA1LKh6YNPg0w\n" + "DQYJKoZIhvcNAQEFBQADggEBAGuZb8ai1NO2j4v3y9TLZvd5s0vh5/TE7n7RX+8U\n" + "y37OL5k7x9nt0mM1TyAKxlCcY+9h6frue8MemZIILSIvMrtzccqNz0V1WKgA+Orf\n" + "uUrabmn+CxHF5gpy6g1Qs2IjVYWA5f7FROn/J+Ad8gJYc1azOWCLQqSyfpNRLSvY\n" + "EriQFEV63XvkJ8JrG62b+2OT2lqT4OO07gSPetppdlSa8NBSKP6Aro9RIX1ZjUZQ\n" + "SpQFCfo02NO0uNRDPUdJx2huycdNb+AXHaO7eXevDLJ+QnqImIzxWiY6zLOdzjjI\n" + "VBMkLHmnP7SjGSQ3XA4ByrQOxfOUTyLyE7NuemhHppuQPxE=\n" + "-----END CERTIFICATE-----\n").getBytes(); /** * subjectAlt=foo.com */ public final static byte[] X509_NO_CNS_FOO = ( "-----BEGIN CERTIFICATE-----\n" + "MIIESjCCAzKgAwIBAgIJAIz+EYMBU6aYMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD\n" + "VQQGEwJDQTELMAkGA1UECBMCQkMxEjAQBgNVBAcTCVZhbmNvdXZlcjEWMBQGA1UE\n" + "ChMNd3d3LmN1Y2JjLmNvbTEUMBIGA1UECxQLY29tbW9uc19zc2wxHTAbBgNVBAMU\n" + "FGRlbW9faW50ZXJtZWRpYXRlX2NhMSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZp\n" + "ZXNAZ21haWwuY29tMB4XDTA2MTIxMTE2MjYxMFoXDTI4MTEwNTE2MjYxMFowgZIx\n" + "CzAJBgNVBAYTAlVTMREwDwYDVQQIDAhNYXJ5bGFuZDEUMBIGA1UEBwwLRm9yZXN0\n" + "IEhpbGwxFzAVBgNVBAoMDmh0dHBjb21wb25lbnRzMRowGAYDVQQLDBF0ZXN0IGNl\n" + "cnRpZmljYXRlczElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWlsLmNv\n" + "bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMhjr5aCPoyp0R1iroWA\n" + "fnEyBMGYWoCidH96yGPFjYLowez5aYKY1IOKTY2BlYho4O84X244QrZTRl8kQbYt\n" + "xnGh4gSCD+Z8gjZ/gMvLUlhqOb+WXPAUHMB39GRyzerA/ZtrlUqf+lKo0uWcocxe\n" + "Rc771KN8cPH3nHZ0rV0Hx4ZAZy6U4xxObe4rtSVY07hNKXAb2odnVqgzcYiDkLV8\n" + "ilvEmoNWMWrp8UBqkTcpEhYhCYp3cTkgJwMSuqv8BqnGd87xQU3FVZI4tbtkB+Kz\n" + "jD9zz8QCDJAfDjZHR03KNQ5mxOgXwxwKw6lGMaiVJTxpTKqym93whYk93l3ocEe5\n" + "5c0CAwEAAaOBkDCBjTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM\n" + "IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUnxR3vz86tso4gkJIFiza\n" + "0Mteh9gwHwYDVR0jBBgwFoAUe5raj5CZTlLSrNuzA1LKh6YNPg0wEgYDVR0RBAsw\n" + "CYIHZm9vLmNvbTANBgkqhkiG9w0BAQUFAAOCAQEAjl78oMjzFdsMy6F1sGg/IkO8\n" + "tF5yUgPgFYrs41yzAca7IQu6G9qtFDJz/7ehh/9HoG+oqCCIHPuIOmS7Sd0wnkyJ\n" + "Y7Y04jVXIb3a6f6AgBkEFP1nOT0z6kjT7vkA5LJ2y3MiDcXuRNMSta5PYVnrX8aZ\n" + "yiqVUNi40peuZ2R8mAUSBvWgD7z2qWhF8YgDb7wWaFjg53I36vWKn90ZEti3wNCw\n" + "qAVqixM+J0qJmQStgAc53i2aTMvAQu3A3snvH/PHTBo+5UL72n9S1kZyNCsVf1Qo\n" + "n8jKTiRriEM+fMFlcgQP284EBFzYHyCXFb9O/hMjK2+6mY9euMB1U1aFFzM/Bg==\n" + "-----END CERTIFICATE-----\n").getBytes(); /** * Intermediate CA for all of these. */ public final static byte[] X509_INTERMEDIATE_CA = ( "-----BEGIN CERTIFICATE-----\n" + "MIIEnDCCA4SgAwIBAgIJAJTNwZ6yNa5cMA0GCSqGSIb3DQEBBQUAMIGGMQswCQYD\n" + "VQQGEwJDQTELMAkGA1UECBMCQkMxFjAUBgNVBAoTDXd3dy5jdWNiYy5jb20xFDAS\n" + "BgNVBAsUC2NvbW1vbnNfc3NsMRUwEwYDVQQDFAxkZW1vX3Jvb3RfY2ExJTAjBgkq\n" + "hkiG9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDYxMTA1MjE0OTMx\n" + "WhcNMDcxMTA1MjE0OTMxWjCBojELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRIw\n" + "EAYDVQQHEwlWYW5jb3V2ZXIxFjAUBgNVBAoTDXd3dy5jdWNiYy5jb20xFDASBgNV\n" + "BAsUC2NvbW1vbnNfc3NsMR0wGwYDVQQDFBRkZW1vX2ludGVybWVkaWF0ZV9jYTEl\n" + "MCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWlsLmNvbTCCASIwDQYJKoZI\n" + "hvcNAQEBBQADggEPADCCAQoCggEBAL0S4y3vUO0EM6lwqOEfK8fvrUprIbsikXaG\n" + "XzejcZ+T3l2Dc7t8WtBfRf78i4JypMqJQSijrUicj3H6mOMIReKaXm6ls4hA5d8w\n" + "Lhmgiqsz/kW+gA8SeWGWRN683BD/RbQmzOls6ynBvap9jZlthXWBrSIlPCQoBLXY\n" + "KVaxGzbL4ezaq+XFMKMQSm2uKwVmHHQNbfmZlPsuendBVomb/ked53Ab9IH6dwwN\n" + "qJH9WIrvIzIVEXWlpvQ5MCqozM7u1akU+G8cazr8theGPCaYkzoXnigWua4OjdpV\n" + "9z5ZDknhfBzG1AjapdG07FIirwWWgIyZXqZSD96ikmLtwT29qnsCAwEAAaOB7jCB\n" + "6zAdBgNVHQ4EFgQUe5raj5CZTlLSrNuzA1LKh6YNPg0wgbsGA1UdIwSBszCBsIAU\n" + "rN8eFIvMiRFXXgDqKumS0/W2AhOhgYykgYkwgYYxCzAJBgNVBAYTAkNBMQswCQYD\n" + "VQQIEwJCQzEWMBQGA1UEChMNd3d3LmN1Y2JjLmNvbTEUMBIGA1UECxQLY29tbW9u\n" + "c19zc2wxFTATBgNVBAMUDGRlbW9fcm9vdF9jYTElMCMGCSqGSIb3DQEJARYWanVs\n" + "aXVzZGF2aWVzQGdtYWlsLmNvbYIJAJTNwZ6yNa5bMAwGA1UdEwQFMAMBAf8wDQYJ\n" + "KoZIhvcNAQEFBQADggEBAIB4KMZvHD20pdKajFtMBpL7X4W4soq6EeTtjml3NYa9\n" + "Qc52bsQEGNccKY9afYSBIndaQvFdtmz6HdoN+B8TjYShw2KhyjtKimGLpWYoi1YF\n" + "e4aHdmA/Gp5xk8pZzR18FmooxC9RqBux+NAM2iTFSLgDtGIIj4sg2rbn6Bb6ZlQT\n" + "1rg6VucXCA1629lNfMeNcu7CBNmUKIdaxHR/YJQallE0KfGRiOIWPrPj/VNk0YA6\n" + "XFg0ocjqXJ2/N0N9rWVshMUaXgOh7m4D/5zga5/nuxDU+PoToA6mQ4bV6eCYqZbh\n" + "aa1kQYtR9B4ZiG6pB82qVc2dCqStOH2FAEWos2gAVkQ=\n" + "-----END CERTIFICATE-----\n").getBytes(); /** * Root CA for all of these. */ public final static byte[] X509_ROOT_CA = ( "-----BEGIN CERTIFICATE-----\n" + "MIIEgDCCA2igAwIBAgIJAJTNwZ6yNa5bMA0GCSqGSIb3DQEBBQUAMIGGMQswCQYD\n" + "VQQGEwJDQTELMAkGA1UECBMCQkMxFjAUBgNVBAoTDXd3dy5jdWNiYy5jb20xFDAS\n" + "BgNVBAsUC2NvbW1vbnNfc3NsMRUwEwYDVQQDFAxkZW1vX3Jvb3RfY2ExJTAjBgkq\n" + "hkiG9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDYxMTA1MjEzNjQz\n" + "WhcNMjYxMTA1MjEzNjQzWjCBhjELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRYw\n" + "FAYDVQQKEw13d3cuY3VjYmMuY29tMRQwEgYDVQQLFAtjb21tb25zX3NzbDEVMBMG\n" + "A1UEAxQMZGVtb19yb290X2NhMSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZpZXNA\n" + "Z21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv+OnocmJ\n" + "79UeO2hlCwK+Cle5uZWnU6uwJl+08z5cvebb5tT64WL9+psDbfgUH/Gm9JsuxKTg\n" + "w1tZO/4duIgnaLNSx4HoqaTjwigd/hR3TsoGEPXTCkz1ikgTCOEDvl+iMid6aOrd\n" + "mViE8HhscxKZ+h5FE7oHZyuT6gFoiaIXhFq+xK2w4ZwDz9L+paiwqywyUJJMnh9U\n" + "jKorY+nua81N0oxpIhHPspCanDU4neMzCzYOZyLR/LqV5xORvHcFY84GWMz5hI25\n" + "JbgaWJsYKuCAvNsnQwVoqKPGa7x1fn7x6oGsXJaCVt8weUwIj2xwg1lxMhrNaisH\n" + "EvKpEAEnGGwWKQIDAQABo4HuMIHrMB0GA1UdDgQWBBSs3x4Ui8yJEVdeAOoq6ZLT\n" + "9bYCEzCBuwYDVR0jBIGzMIGwgBSs3x4Ui8yJEVdeAOoq6ZLT9bYCE6GBjKSBiTCB\n" + "hjELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRYwFAYDVQQKEw13d3cuY3VjYmMu\n" + "Y29tMRQwEgYDVQQLFAtjb21tb25zX3NzbDEVMBMGA1UEAxQMZGVtb19yb290X2Nh\n" + "MSUwIwYJKoZIhvcNAQkBFhZqdWxpdXNkYXZpZXNAZ21haWwuY29tggkAlM3BnrI1\n" + "rlswDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAlPl3/8h1LttR1svC\n" + "S8RXbHpAWIT2BEDhGHUNjSmgDQNkE/itf/FCEXh0tlU4bYdtBSOHzflbnzOyIPId\n" + "VZeSWs33V38xDFy6KoVg1gT8JxkLmE5S1vWkpsHIlpw/U6r7KD0Kx9FYx5AiXjw0\n" + "lzz/zlVNuO2U09KIDwDPVG1mBzQiMiSWj1U1pM4KxINkWQwDy/fvu/I983s8lW5z\n" + "hf2WuFNzQN3fcMK5dpBE9NVIu27oYuGYh2sak34v+7T700W2ooBB71qFXtm9P5rl\n" + "Yp9RCEsg3KEEPNTtCBs8fROeXvLDrP0cmBIqwGYDuRNCxFDTOdjv6YGdA8nLOjaH\n" + "2dDk0g==\n" + "-----END CERTIFICATE-----\n").getBytes(); /** * Below is the private key for all the server certificates above (but * not the intermediate CA or the root CA). All of those server certs * came from the same private key. */ public final static String RSA_PUBLIC_MODULUS = "00c863af96823e8ca9d11d62ae85807e713204c1985a80a2747f7ac863c5" + "8d82e8c1ecf9698298d4838a4d8d81958868e0ef385f6e3842b653465f24" + "41b62dc671a1e204820fe67c82367f80cbcb52586a39bf965cf0141cc077" + "f46472cdeac0fd9b6b954a9ffa52a8d2e59ca1cc5e45cefbd4a37c70f1f7" + "9c7674ad5d07c78640672e94e31c4e6dee2bb52558d3b84d29701bda8767" + "56a83371888390b57c8a5bc49a8356316ae9f1406a913729121621098a77" + "713920270312baabfc06a9c677cef1414dc5559238b5bb6407e2b38c3f73" + "cfc4020c901f0e3647474dca350e66c4e817c31c0ac3a94631a895253c69" + "4caab29bddf085893dde5de87047b9e5cd"; public final static String RSA_PUBLIC_EXPONENT = "65537"; public final static String RSA_PRIVATE_EXPONENT = "577abd3295553d0efd4d38c13b62a6d03fa7b7e40cce4f1d5071877d96c6" + "7a39a63f0f7ab21a89db8acae45587b3ef251309a70f74dc1ac02bde68f3" + "8ed658e54e685ed370a18c054449512ea66a2252ed36e82b565b5159ec83" + "f23df40ae189550a183865b25fd77789e960f0d8cedcd72f32d7a66edb4b" + "a0a2baf3fbeb6c7d75f56ef0af9a7cff1c8c7f297d72eae7982164e50a89" + "d450698cf598d39343201094241d2d180a95882a7111e58f4a5bdbc5c125" + "a967dd6ed9ec614c5853e88e4c71e8b682a7cf89cb1d82b6fe78cc865084" + "c8c5dfbb50c939df2b839c977b0245bfa3615e0592b527b1013d5b675ecb" + "44e6b355c1df581f50997175166eef39"; public final static String RSA_PRIME1 = "00fe759c4f0ce8b763880215e82767e7a937297668f4e4b1e119c6b22a3c" + "a2c7b06c547d88d0aa45f645d7d3aeadaf7f8bc594deae0978529592977c" + "b1ff890f05033a9e9e15551cad9fbf9c41d12139ccd99c1c3ac7b2197eff" + "350d236bb900c1440953b64956e0a058ef824a2e16894af175177c77dbe1" + "fef7d8b532608d2513"; public final static String RSA_PRIME2 = "00c99a45878737a4cf73f9896680b75487f1b669b7686a6ba07103856f31" + "db668c2c440c44cdd116f708f631c37a9adf119f5b5cb58ffe3dc62e20af" + "af72693d936dc6bb3c5194996468389c1f094079b81522e94572b4ad7d39" + "529178e9b8ebaeb1f0fdd83b8731c5223f1dea125341d1d64917f6b1a6ae" + "c18d320510d79f859f"; public final static String RSA_EXPONENT1 = "029febf0d4cd41b7011c2465b4a259bd6118486464c247236f44a169d61e" + "47b9062508f674508d5031003ceabc57e714e600d71b2c75d5443db2da52" + "6bb45a374f0537c5a1aab3150764ce93cf386c84346a6bd01f6732e42075" + "c7a0e9e78a9e73b934e7d871d0f75673820089e129a1604438edcbbeb4e2" + "106467da112ce389"; public final static String RSA_EXPONENT2 = "00827e76650c946afcd170038d32e1f8386ab00d6be78d830efe382e45d4" + "7ad4bd04e6231ee22e66740efbf52838134932c9f8c460cdccdec58a1424" + "4427859192fd6ab6c58b74e97941b0eaf577f2a11713af5e5952af3ae124" + "9a9a892e98410dfa2628d9af668a43b5302fb7d496c9b2fec69f595292b6" + "e997f079b0f6314eb7"; public final static String RSA_COEFFICIENT = "00e6b62add350f1a2a8968903ff76c31cf703b0d7326c4a620aef01225b7" + "1640b3f2ec375208c5f7299863f6005b7799b6e529bb1133c8435bf5fdb5" + "a786f6cd8a19ee7094a384e6557c600a38845a0960ddbfd1df18d0af5740" + "001853788f1b5ccbf9affb4c52c9d2efdb8aab0183d86735b32737fb4e79" + "2b8a9c7d91c7d175ae"; /** * subjectAlt=IP Address:127.0.0.1, email:oleg@ural.ru, DNS:localhost.localdomain */ public final static byte[] X509_MULTIPLE_SUBJECT_ALT = ( "-----BEGIN CERTIFICATE-----\n" + "MIIDcTCCAtqgAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMQswCQYDVQQGEwJDSDEL\n" + "MAkGA1UECBMCWkgxDzANBgNVBAcTBlp1cmljaDETMBEGA1UEAxMKTXkgVGVzdCBD\n" + "QTAeFw0wODEwMzExMTU3NDVaFw0wOTEwMzExMTU3NDVaMGkxCzAJBgNVBAYTAkNI\n" + "MRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYDVQQKEwdV\n" + "bmtub3duMRAwDgYDVQQLEwdVbmtub3duMRIwEAYDVQQDEwlsb2NhbGhvc3QwggG4\n" + "MIIBLAYHKoZIzjgEATCCAR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/\n" + "gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQ\n" + "IsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZ\n" + "ndFIAccCFQCXYFCPFSMLzLKSuYKi64QL8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5\n" + "eZSvu/o66oL5V0wLPQeCZ1FZV4661FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbh\n" + "PBZ6i1R8jSjgo64eK7OmdZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8G\n" + "kotmXoB7VSVkAUw7/s9JKgOBhQACgYEA6ogAb/YLM1Rz9AoXKW4LA70VtFf7Mqqp\n" + "divdu9f72WQc1vMKo1YMf3dQadkMfBYRvAAa1IXDnoiFCHhXnVRkWkoUBJyNebLB\n" + "N92CZc0RVFZiMFgQMEh8UldnvAIi4cBk0/YuN3BGl4MzmquVIGrFovdWGqeaveOu\n" + "Xcu4lKGJNiqjODA2MDQGA1UdEQQtMCuHBH8AAAGBDG9sZWdAdXJhbC5ydYIVbG9j\n" + "YWxob3N0LmxvY2FsZG9tYWluMA0GCSqGSIb3DQEBBQUAA4GBAIgEwIoCSRkU3O7K\n" + "USYaOYyfJB9hsvs6YpClvYXiQ/5kPGARP60pM62v4wC7wI9shEizokIAxY2+O3cC\n" + "vwuJhNYaa2FJMELIwRN3XES8X8R6JHWbPaRjaAAPhczuEd8SZYy8yiVLmJTgw0gH\n" + "BSW775NHlkjsscFVgXkNf0PobqJ9\n" + "-----END CERTIFICATE-----").getBytes(); /** * subject CN=repository.infonotary.com (Multiple AVA in RDN). */ public final static byte[] X509_MULTIPLE_VALUE_AVA = ( "-----BEGIN CERTIFICATE-----\n" + "MIIFxzCCBK+gAwIBAgIIRO/2+/XA7z4wDQYJKoZIhvcNAQEFBQAwgZwxgZkwCQYD\n" + "VQQGDAJCRzAVBgNVBAoMDkluZm9Ob3RhcnkgUExDMBcGCgmSJomT8ixkARkWCWRv\n" + "bWFpbi1jYTAtBgNVBAMMJmktTm90YXJ5IFRydXN0UGF0aCBWYWxpZGF0ZWQgRG9t\n" + "YWluIENBMC0GA1UECwwmaS1Ob3RhcnkgVHJ1c3RQYXRoIFZhbGlkYXRlZCBEb21h\n" + "aW4gQ0EwHhcNMTIwNjE4MDg1MzIyWhcNMTMwNjE4MDg1MzIyWjCBxjGBwzAJBgNV\n" + "BAYTAkJHMBUGA1UEChMOSW5mb05vdGFyeSBQTEMwFwYDVQQLExBGaWxlcyBSZXBv\n" + "c2l0b3J5MBcGCgmSJomT8ixkARkWCWRvbWFpbi1jYTAgBgNVBAMTGXJlcG9zaXRv\n" + "cnkuaW5mb25vdGFyeS5jb20wIwYJKoZIhvcNAQkBFhZzdXBwb3J0QGluZm9ub3Rh\n" + "cnkuY29tMCYGCSqGSIb3DQEJAhMZcmVwb3NpdG9yeS5pbmZvbm90YXJ5LmNvbTCC\n" + "ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALKWjGpgsuz103xVEW/GSg5I\n" + "tBoLbXPxockabOTHnOh0VO2sImycyhBH78nMj+VMexn4y+kdCOuJqAA5LApxyhTA\n" + "KgKlRN7TfoC90IYHjB1dqLMIseg4YM7Oe0e4Z2nL50bHoqXg7OUHaILUQn7ufpYp\n" + "+VCWxyI43KvaR4+HnST3x47wqeArg/rULGV1a16X+46cxq2eoMAcDfostXHaemvz\n" + "vg/Wd5xcWfPbF/oY1/sBXH+AK+peVBMen82+3GtAWtNWbyPE3bT4RG+WgKUyfLZ1\n" + "7A67rX9DkUEVMPQpa50MpLnrRveiM9w6R3mrMHMHbNnwID0Tqfds5zzOi/7cLD0C\n" + "AwEAAaOCAd8wggHbMA4GA1UdDwEB/wQEAwIDuDATBgNVHSUEDDAKBggrBgEFBQcD\n" + "ATBEBggrBgEFBQcBAQQ4MDYwNAYIKwYBBQUHMAGGKGh0dHA6Ly9vY3NwLmluZm9u\n" + "b3RhcnkuY29tL3Jlc3BvbmRlci5jZ2kwgZAGA1UdIASBiDCBhTCBggYMKwYBBAGB\n" + "rQABAgMBMHIwOAYIKwYBBQUHAgEWLGh0dHA6Ly9yZXBvc2l0b3J5LmluZm9ub3Rh\n" + "cnkuY29tL2RvbWFpbi5odG1sMDYGCCsGAQUFBwICMCoaKGktTm90YXJ5IFZhbGlk\n" + "YXRlZCBEb21haW4gQ2VydGlmaWNhdGUgQ1AwgYkGA1UdHwSBgTB/MDWgL6Athito\n" + "dHRwOi8vY3JsLmluZm9ub3RhcnkuY29tL2NybC9kb21haW4tY2EuY3JsgQIBVjBG\n" + "oECgPoY8bGRhcDovL2xkYXAuaW5mb25vdGFyeS5jb20vZGM9ZG9tYWluLWNhLGRj\n" + "PWluZm9ub3RhcnksZGM9Y29tgQIBVjAPBgNVHRMBAf8EBTADAQEAMB0GA1UdDgQW\n" + "BBTImKJZrgV/8n7mHrA0U5EeGsBvbzAfBgNVHSMEGDAWgBTbkorEK+bPdVPpvyVI\n" + "PTxGFnuOoDANBgkqhkiG9w0BAQUFAAOCAQEAhsMbqsqvkbfVaKZ+wDY9rX3EtuDS\n" + "isdAo4AjmWgTtj/aBGiEiXcIGP312x+0JF+mEEQ75ZOKN+WsM8eLB0F4aqylklk7\n" + "6yRYauRXp8dfbXrT3ozxekt0cpSMqbzze456krI12nL+C00V2Iwq96k5J/yZboNW\n" + "Q+ibCaEAHNiL4tGVHSHm6znkWvIuUTbDgDEsm5RdafO27suz5H6zMnV+VE6onN1J\n" + "I1mQmUs44cg2HZAqnFBpDyJQhNYy8M7yGVaRkbfuVaMqiPa+xDPR5v7NFB3kxRq2\n" + "Za2Snopi52eUxDEhJ0MNqFi3Jfj/ZSmJ+XHra5lU4R8lijCAq8SVLZCmIQ==\n" + "-----END CERTIFICATE-----").getBytes(); } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/ssl/TestHostnameVerifier.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/ssl/TestHostnameVerifier.j0100644 0000000 0000000 00000037430 12301751653 032502 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.security.Principal; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Arrays; import javax.net.ssl.SSLException; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; /** * Unit tests for {@link X509HostnameVerifier}. */ public class TestHostnameVerifier { @Test public void testVerify() throws Exception { final X509HostnameVerifier DEFAULT = new BrowserCompatHostnameVerifier(); final X509HostnameVerifier STRICT = new StrictHostnameVerifier(); final X509HostnameVerifier ALLOW_ALL = new AllowAllHostnameVerifier(); final CertificateFactory cf = CertificateFactory.getInstance("X.509"); InputStream in; X509Certificate x509; in = new ByteArrayInputStream(CertificatesToPlayWith.X509_FOO); x509 = (X509Certificate) cf.generateCertificate(in); DEFAULT.verify("foo.com", x509); STRICT.verify("foo.com", x509); exceptionPlease(DEFAULT, "a.foo.com", x509); exceptionPlease(STRICT, "a.foo.com", x509); exceptionPlease(DEFAULT, "bar.com", x509); exceptionPlease(STRICT, "bar.com", x509); ALLOW_ALL.verify("foo.com", x509); ALLOW_ALL.verify("a.foo.com", x509); ALLOW_ALL.verify("bar.com", x509); in = new ByteArrayInputStream(CertificatesToPlayWith.X509_HANAKO); x509 = (X509Certificate) cf.generateCertificate(in); DEFAULT.verify("\u82b1\u5b50.co.jp", x509); STRICT.verify("\u82b1\u5b50.co.jp", x509); exceptionPlease(DEFAULT, "a.\u82b1\u5b50.co.jp", x509); exceptionPlease(STRICT, "a.\u82b1\u5b50.co.jp", x509); in = new ByteArrayInputStream(CertificatesToPlayWith.X509_FOO_BAR); x509 = (X509Certificate) cf.generateCertificate(in); DEFAULT.verify("foo.com", x509); STRICT.verify("foo.com", x509); exceptionPlease(DEFAULT, "a.foo.com", x509); exceptionPlease(STRICT, "a.foo.com", x509); DEFAULT.verify("bar.com", x509); STRICT.verify("bar.com", x509); exceptionPlease(DEFAULT, "a.bar.com", x509); exceptionPlease(STRICT, "a.bar.com", x509); in = new ByteArrayInputStream(CertificatesToPlayWith.X509_FOO_BAR_HANAKO); x509 = (X509Certificate) cf.generateCertificate(in); DEFAULT.verify("foo.com", x509); STRICT.verify("foo.com", x509); exceptionPlease(DEFAULT, "a.foo.com", x509); exceptionPlease(STRICT, "a.foo.com", x509); DEFAULT.verify("bar.com", x509); STRICT.verify("bar.com", x509); exceptionPlease(DEFAULT, "a.bar.com", x509); exceptionPlease(STRICT, "a.bar.com", x509); /* Java isn't extracting international subjectAlts properly. (Or OpenSSL isn't storing them properly). */ // DEFAULT.verify("\u82b1\u5b50.co.jp", x509 ); // STRICT.verify("\u82b1\u5b50.co.jp", x509 ); exceptionPlease(DEFAULT, "a.\u82b1\u5b50.co.jp", x509); exceptionPlease(STRICT, "a.\u82b1\u5b50.co.jp", x509); in = new ByteArrayInputStream(CertificatesToPlayWith.X509_NO_CNS_FOO); x509 = (X509Certificate) cf.generateCertificate(in); DEFAULT.verify("foo.com", x509); STRICT.verify("foo.com", x509); exceptionPlease(DEFAULT, "a.foo.com", x509); exceptionPlease(STRICT, "a.foo.com", x509); in = new ByteArrayInputStream(CertificatesToPlayWith.X509_NO_CNS_FOO); x509 = (X509Certificate) cf.generateCertificate(in); DEFAULT.verify("foo.com", x509); STRICT.verify("foo.com", x509); exceptionPlease(DEFAULT, "a.foo.com", x509); exceptionPlease(STRICT, "a.foo.com", x509); in = new ByteArrayInputStream(CertificatesToPlayWith.X509_THREE_CNS_FOO_BAR_HANAKO); x509 = (X509Certificate) cf.generateCertificate(in); exceptionPlease(DEFAULT, "foo.com", x509); exceptionPlease(STRICT, "foo.com", x509); exceptionPlease(DEFAULT, "a.foo.com", x509); exceptionPlease(STRICT, "a.foo.com", x509); exceptionPlease(DEFAULT, "bar.com", x509); exceptionPlease(STRICT, "bar.com", x509); exceptionPlease(DEFAULT, "a.bar.com", x509); exceptionPlease(STRICT, "a.bar.com", x509); DEFAULT.verify("\u82b1\u5b50.co.jp", x509); STRICT.verify("\u82b1\u5b50.co.jp", x509); exceptionPlease(DEFAULT, "a.\u82b1\u5b50.co.jp", x509); exceptionPlease(STRICT, "a.\u82b1\u5b50.co.jp", x509); in = new ByteArrayInputStream(CertificatesToPlayWith.X509_WILD_FOO); x509 = (X509Certificate) cf.generateCertificate(in); exceptionPlease(DEFAULT, "foo.com", x509); exceptionPlease(STRICT, "foo.com", x509); DEFAULT.verify("www.foo.com", x509); STRICT.verify("www.foo.com", x509); DEFAULT.verify("\u82b1\u5b50.foo.com", x509); STRICT.verify("\u82b1\u5b50.foo.com", x509); DEFAULT.verify("a.b.foo.com", x509); exceptionPlease(STRICT, "a.b.foo.com", x509); in = new ByteArrayInputStream(CertificatesToPlayWith.X509_WILD_CO_JP); x509 = (X509Certificate) cf.generateCertificate(in); // Silly test because no-one would ever be able to lookup an IP address // using "*.co.jp". DEFAULT.verify("*.co.jp", x509); STRICT.verify("*.co.jp", x509); DEFAULT.verify("foo.co.jp", x509); exceptionPlease(STRICT, "foo.co.jp", x509); DEFAULT.verify("\u82b1\u5b50.co.jp", x509); exceptionPlease(STRICT, "\u82b1\u5b50.co.jp", x509); in = new ByteArrayInputStream(CertificatesToPlayWith.X509_WILD_FOO_BAR_HANAKO); x509 = (X509Certificate) cf.generateCertificate(in); // try the foo.com variations exceptionPlease(DEFAULT, "foo.com", x509); exceptionPlease(STRICT, "foo.com", x509); DEFAULT.verify("www.foo.com", x509); STRICT.verify("www.foo.com", x509); DEFAULT.verify("\u82b1\u5b50.foo.com", x509); STRICT.verify("\u82b1\u5b50.foo.com", x509); DEFAULT.verify("a.b.foo.com", x509); exceptionPlease(STRICT, "a.b.foo.com", x509); // try the bar.com variations exceptionPlease(DEFAULT, "bar.com", x509); exceptionPlease(STRICT, "bar.com", x509); DEFAULT.verify("www.bar.com", x509); STRICT.verify("www.bar.com", x509); DEFAULT.verify("\u82b1\u5b50.bar.com", x509); STRICT.verify("\u82b1\u5b50.bar.com", x509); DEFAULT.verify("a.b.bar.com", x509); exceptionPlease(STRICT, "a.b.bar.com", x509); // try the \u82b1\u5b50.co.jp variations /* Java isn't extracting international subjectAlts properly. (Or OpenSSL isn't storing them properly). */ //exceptionPlease( DEFAULT, "\u82b1\u5b50.co.jp", x509 ); //exceptionPlease( STRICT, "\u82b1\u5b50.co.jp", x509 ); //DEFAULT.verify("www.\u82b1\u5b50.co.jp", x509 ); //STRICT.verify("www.\u82b1\u5b50.co.jp", x509 ); //DEFAULT.verify("\u82b1\u5b50.\u82b1\u5b50.co.jp", x509 ); //STRICT.verify("\u82b1\u5b50.\u82b1\u5b50.co.jp", x509 ); //DEFAULT.verify("a.b.\u82b1\u5b50.co.jp", x509 ); //exceptionPlease(STRICT,"a.b.\u82b1\u5b50.co.jp", x509 ); in = new ByteArrayInputStream(CertificatesToPlayWith.X509_MULTIPLE_VALUE_AVA); x509 = (X509Certificate) cf.generateCertificate(in); ALLOW_ALL.verify("repository.infonotary.com", x509); DEFAULT.verify("repository.infonotary.com", x509); STRICT.verify("repository.infonotary.com", x509); } @Test public void testSubjectAlt() throws Exception { final CertificateFactory cf = CertificateFactory.getInstance("X.509"); final InputStream in = new ByteArrayInputStream(CertificatesToPlayWith.X509_MULTIPLE_SUBJECT_ALT); final X509Certificate x509 = (X509Certificate) cf.generateCertificate(in); final X509HostnameVerifier verifier = SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; Assert.assertEquals("CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=CH", x509.getSubjectDN().getName()); verifier.verify("localhost", x509); verifier.verify("localhost.localdomain", x509); verifier.verify("127.0.0.1", x509); try { verifier.verify("local.host", x509); Assert.fail("SSLException should have been thrown"); } catch (final SSLException ex) { // expected } try { verifier.verify("127.0.0.2", x509); Assert.fail("SSLException should have been thrown"); } catch (final SSLException ex) { // expected } } public void exceptionPlease(final X509HostnameVerifier hv, final String host, final X509Certificate x509) { try { hv.verify(host, x509); Assert.fail("HostnameVerifier shouldn't allow [" + host + "]"); } catch(final SSLException e) { // whew! we're okay! } } // Test helper method private void checkMatching(final X509HostnameVerifier hv, final String host, final String[] cns, final String[] alts, final boolean shouldFail) { try { hv.verify(host, cns, alts); if (shouldFail) { Assert.fail("HostnameVerifier should not allow [" + host + "] to match " +Arrays.toString(cns) +" or " +Arrays.toString(alts)); } } catch(final SSLException e) { if (!shouldFail) { Assert.fail("HostnameVerifier should have allowed [" + host + "] to match " +Arrays.toString(cns) +" or " +Arrays.toString(alts)); } } } @Test // Check standard wildcard matching public void testMatching() { String cns[] = {}; String alt[] = {}; final X509HostnameVerifier bhv = new BrowserCompatHostnameVerifier(); final X509HostnameVerifier shv = new StrictHostnameVerifier(); checkMatching(bhv, "a.b.c", cns, alt, true); // empty checkMatching(shv, "a.b.c", cns, alt, true); // empty cns = new String []{"*.b.c"}; checkMatching(bhv, "a.b.c", cns, alt, false); // OK checkMatching(shv, "a.b.c", cns, alt, false); // OK checkMatching(bhv, "s.a.b.c", cns, alt, false); // OK checkMatching(shv, "s.a.b.c", cns, alt, true); // subdomain not OK cns = new String []{}; alt = new String []{"dummy", "*.b.c"}; // check matches against all alts checkMatching(bhv, "a.b.c", cns, alt, false); // OK checkMatching(shv, "a.b.c", cns, alt, false); // OK checkMatching(bhv, "s.a.b.c", cns, alt, false); // OK checkMatching(shv, "s.a.b.c", cns, alt, true); // subdomain not OK alt = new String []{"*.gov.uk"}; checkMatching(bhv, "a.gov.uk", cns, alt, false); // OK checkMatching(shv, "a.gov.uk", cns, alt, true); // Bad 2TLD checkMatching(bhv, "s.a.gov.uk", cns, alt, false); // OK checkMatching(shv, "s.a.gov.uk", cns, alt, true); // Bad 2TLD/no subdomain allowed alt = new String []{"*.gov.com"}; checkMatching(bhv, "a.gov.com", cns, alt, false); // OK, gov not 2TLD here checkMatching(shv, "a.gov.com", cns, alt, false); // OK, gov not 2TLD here checkMatching(bhv, "s.a.gov.com", cns, alt, false); // OK, gov not 2TLD here checkMatching(shv, "s.a.gov.com", cns, alt, true); // no subdomain allowed cns = new String []{"a*.gov.uk"}; // 2TLD check applies to wildcards checkMatching(bhv, "a.gov.uk", cns, alt, false); // OK checkMatching(shv, "a.gov.uk", cns, alt, true); // Bad 2TLD checkMatching(bhv, "s.a.gov.uk", cns, alt, true); // Bad 2TLD checkMatching(shv, "s.a.gov.uk", cns, alt, true); // Bad 2TLD/no subdomain allowed } @Test // Check compressed IPv6 hostname matching public void testHTTPCLIENT_1316() throws Exception{ final String cns[] = {"2001:0db8:aaaa:bbbb:cccc:0:0:0001"}; final String alt[] = {}; final X509HostnameVerifier bhv = new BrowserCompatHostnameVerifier(); final X509HostnameVerifier shv = new StrictHostnameVerifier(); checkMatching(bhv, "2001:0db8:aaaa:bbbb:cccc:0:0:0001", cns, alt, false); checkMatching(shv, "2001:0db8:aaaa:bbbb:cccc:0:0:0001", cns, alt, false); checkMatching(bhv, "2001:0db8:aaaa:bbbb:cccc::1", cns, alt, false); checkMatching(shv, "2001:0db8:aaaa:bbbb:cccc::1", cns, alt, false); checkMatching(bhv, "2001:0db8:aaaa:bbbb:cccc::10", cns, alt, true); checkMatching(shv, "2001:0db8:aaaa:bbbb:cccc::10", cns, alt, true); // TODO need some more samples } @Test public void testHTTPCLIENT_1097() { String cns[]; final String alt[] = {}; final X509HostnameVerifier bhv = new BrowserCompatHostnameVerifier(); final X509HostnameVerifier shv = new StrictHostnameVerifier(); cns = new String []{"a*.b.c"}; // component part checkMatching(bhv, "a.b.c", cns, alt, false); // OK checkMatching(shv, "a.b.c", cns, alt, false); // OK checkMatching(bhv, "a.a.b.c", cns, alt, false); // OK checkMatching(shv, "a.a.b.c", cns, alt, true); // subdomain not OK } @Test public void testHTTPCLIENT_1255() { final X509HostnameVerifier bhv = new BrowserCompatHostnameVerifier(); final X509HostnameVerifier shv = new StrictHostnameVerifier(); final String cns[] = new String []{"m*.a.b.c.com"}; // component part final String alt[] = {}; checkMatching(bhv, "mail.a.b.c.com", cns, alt, false); // OK checkMatching(shv, "mail.a.b.c.com", cns, alt, false); // OK } public void testGetCNs() { final Principal principal = Mockito.mock(Principal.class); final X509Certificate cert = Mockito.mock(X509Certificate.class); Mockito.when(cert.getSubjectDN()).thenReturn(principal); Mockito.when(principal.toString()).thenReturn("bla, bla, blah"); Assert.assertArrayEquals(new String[] {}, AbstractVerifier.getCNs(cert)); Mockito.when(principal.toString()).thenReturn("Cn=, Cn= , CN, OU=CN="); Assert.assertArrayEquals(new String[] {}, AbstractVerifier.getCNs(cert)); Mockito.when(principal.toString()).thenReturn(" Cn=blah, CN= blah , OU=CN=yada"); Assert.assertArrayEquals(new String[] {"blah", " blah"}, AbstractVerifier.getCNs(cert)); } } ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLContextBuilder.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLContextBuilder.0100644 0000000 0000000 00000007173 12301751653 032374 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import java.io.InputStream; import java.net.URL; import java.security.KeyStore; import java.security.UnrecoverableKeyException; import org.junit.Test; /** * Unit tests for {@link org.apache.http.conn.ssl.SSLContextBuilder}. */ public class TestSSLContextBuilder { private static KeyStore load(final String res, final char[] passwd) throws Exception { final KeyStore keystore = KeyStore.getInstance("jks"); final ClassLoader cl = TestSSLContextBuilder.class.getClassLoader(); final URL url = cl.getResource(res); final InputStream instream = url.openStream(); try { keystore.load(instream, passwd); } finally { instream.close(); } return keystore; } @Test public void testBuildDefault() throws Exception { new SSLContextBuilder().build(); } @Test public void testBuildAllNull() throws Exception { new SSLContextBuilder() .useProtocol(null) .setSecureRandom(null) .loadTrustMaterial(null) .loadKeyMaterial(null, null) .build(); } @Test public void testLoadTrustMultipleMaterial() throws Exception { final KeyStore truststore1 = load("hc-test-1.truststore", "nopassword".toCharArray()); final KeyStore truststore2 = load("hc-test-2.truststore", "nopassword".toCharArray()); new SSLContextBuilder() .loadTrustMaterial(truststore1) .loadTrustMaterial(truststore2) .build(); } @Test public void testKeyWithAlternatePassword() throws Exception { final KeyStore keystore = load("test-keypasswd.keystore", "nopassword".toCharArray()); final String keyPassword = "password"; new SSLContextBuilder() .loadKeyMaterial(keystore, keyPassword != null ? keyPassword.toCharArray() : null) .loadTrustMaterial(keystore) .build(); } @Test(expected=UnrecoverableKeyException.class) public void testKeyWithAlternatePasswordInvalid() throws Exception { final KeyStore keystore = load("test-keypasswd.keystore", "nopassword".toCharArray()); final String keyPassword = "!password"; new SSLContextBuilder() .loadKeyMaterial(keystore, keyPassword != null ? keyPassword.toCharArray() : null) .loadTrustMaterial(keystore) .build(); } } ././@LongLink0100644 0000000 0000000 00000000150 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/ssl/TestSSLSocketFactory.j0100644 0000000 0000000 00000031014 12301751654 032363 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.ssl; import java.io.IOException; import java.io.InputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.net.URL; import java.security.KeyStore; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Map; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import org.apache.http.HttpHost; import org.apache.http.localserver.LocalServerTestBase; import org.apache.http.localserver.LocalTestServer; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * Unit tests for {@link SSLConnectionSocketFactory}. */ public class TestSSLSocketFactory extends LocalServerTestBase { private KeyStore keystore; @Before public void setUp() throws Exception { keystore = KeyStore.getInstance("jks"); final ClassLoader cl = getClass().getClassLoader(); final URL url = cl.getResource("hc-test.keystore"); final InputStream instream = url.openStream(); try { keystore.load(instream, "nopassword".toCharArray()); } finally { instream.close(); } } @Override protected HttpHost getServerHttp() { final InetSocketAddress address = this.localServer.getServiceAddress(); return new HttpHost( address.getHostName(), address.getPort(), "https"); } static class TestX509HostnameVerifier implements X509HostnameVerifier { private boolean fired = false; public boolean verify(final String host, final SSLSession session) { return true; } public void verify(final String host, final SSLSocket ssl) throws IOException { this.fired = true; } public void verify(final String host, final String[] cns, final String[] subjectAlts) throws SSLException { } public void verify(final String host, final X509Certificate cert) throws SSLException { } public boolean isFired() { return this.fired; } } @Test public void testBasicSSL() throws Exception { final SSLContext serverSSLContext = SSLContexts.custom() .useProtocol("TLS") .loadTrustMaterial(keystore) .loadKeyMaterial(keystore, "nopassword".toCharArray()) .build(); final SSLContext clientSSLContext = SSLContexts.custom() .useProtocol("TLS") .loadTrustMaterial(keystore) .build(); this.localServer = new LocalTestServer(serverSSLContext); this.localServer.registerDefaultHandlers(); this.localServer.start(); final HttpHost host = new HttpHost("localhost", 443, "https"); final HttpContext context = new BasicHttpContext(); final TestX509HostnameVerifier hostVerifier = new TestX509HostnameVerifier(); final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( clientSSLContext, hostVerifier); final Socket socket = socketFactory.createSocket(context); final InetSocketAddress remoteAddress = this.localServer.getServiceAddress(); final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket(0, socket, host, remoteAddress, null, context); final SSLSession sslsession = sslSocket.getSession(); Assert.assertNotNull(sslsession); Assert.assertTrue(hostVerifier.isFired()); } @Test public void testClientAuthSSL() throws Exception { final SSLContext serverSSLContext = SSLContexts.custom() .useProtocol("TLS") .loadTrustMaterial(keystore) .loadKeyMaterial(keystore, "nopassword".toCharArray()) .build(); final SSLContext clientSSLContext = SSLContexts.custom() .useProtocol("TLS") .loadTrustMaterial(keystore) .loadKeyMaterial(keystore, "nopassword".toCharArray()) .build(); this.localServer = new LocalTestServer(serverSSLContext, true); this.localServer.registerDefaultHandlers(); this.localServer.start(); final HttpHost host = new HttpHost("localhost", 443, "https"); final HttpContext context = new BasicHttpContext(); final TestX509HostnameVerifier hostVerifier = new TestX509HostnameVerifier(); final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(clientSSLContext, hostVerifier); final Socket socket = socketFactory.createSocket(context); final InetSocketAddress remoteAddress = this.localServer.getServiceAddress(); final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket(0, socket, host, remoteAddress, null, context); final SSLSession sslsession = sslSocket.getSession(); Assert.assertNotNull(sslsession); Assert.assertTrue(hostVerifier.isFired()); } @Test(expected=IOException.class) public void testClientAuthSSLFailure() throws Exception { final SSLContext serverSSLContext = SSLContexts.custom() .useProtocol("TLS") .loadTrustMaterial(keystore) .loadKeyMaterial(keystore, "nopassword".toCharArray()) .build(); final SSLContext clientSSLContext = SSLContexts.custom() .useProtocol("TLS") .loadTrustMaterial(keystore) .build(); this.localServer = new LocalTestServer(serverSSLContext, true); this.localServer.registerDefaultHandlers(); this.localServer.start(); final HttpHost host = new HttpHost("localhost", 443, "https"); final HttpContext context = new BasicHttpContext(); final TestX509HostnameVerifier hostVerifier = new TestX509HostnameVerifier(); final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(clientSSLContext, hostVerifier); final Socket socket = socketFactory.createSocket(context); final InetSocketAddress remoteAddress = this.localServer.getServiceAddress(); final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket(0, socket, host, remoteAddress, null, context); final SSLSession sslsession = sslSocket.getSession(); Assert.assertNotNull(sslsession); Assert.assertTrue(hostVerifier.isFired()); } @Test public void testClientAuthSSLAliasChoice() throws Exception { final PrivateKeyStrategy aliasStrategy = new PrivateKeyStrategy() { public String chooseAlias( final Map aliases, final Socket socket) { Assert.assertEquals(2, aliases.size()); Assert.assertTrue(aliases.containsKey("hc-test-key-1")); Assert.assertTrue(aliases.containsKey("hc-test-key-2")); return "hc-test-key-2"; } }; final SSLContext serverSSLContext = SSLContexts.custom() .useProtocol("TLS") .loadTrustMaterial(keystore) .loadKeyMaterial(keystore, "nopassword".toCharArray()) .build(); final SSLContext clientSSLContext = SSLContexts.custom() .useProtocol("TLS") .loadTrustMaterial(keystore) .loadKeyMaterial(keystore, "nopassword".toCharArray(), aliasStrategy) .build(); this.localServer = new LocalTestServer(serverSSLContext, true); this.localServer.registerDefaultHandlers(); this.localServer.start(); final HttpHost host = new HttpHost("localhost", 443, "https"); final HttpContext context = new BasicHttpContext(); final TestX509HostnameVerifier hostVerifier = new TestX509HostnameVerifier(); final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(clientSSLContext, hostVerifier); final Socket socket = socketFactory.createSocket(context); final InetSocketAddress remoteAddress = this.localServer.getServiceAddress(); final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket(0, socket, host, remoteAddress, null, context); final SSLSession sslsession = sslSocket.getSession(); Assert.assertNotNull(sslsession); Assert.assertTrue(hostVerifier.isFired()); } @Test(expected=SSLHandshakeException.class) public void testSSLTrustVerification() throws Exception { final SSLContext serverSSLContext = SSLContexts.custom() .useProtocol("TLS") .loadTrustMaterial(keystore) .loadKeyMaterial(keystore, "nopassword".toCharArray()) .build(); this.localServer = new LocalTestServer(serverSSLContext); this.localServer.registerDefaultHandlers(); this.localServer.start(); final HttpHost host = new HttpHost("localhost", 443, "https"); final HttpContext context = new BasicHttpContext(); // Use default SSL context final SSLContext defaultsslcontext = SSLContexts.createDefault(); final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(defaultsslcontext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); final Socket socket = socketFactory.createSocket(context); final InetSocketAddress remoteAddress = this.localServer.getServiceAddress(); socketFactory.connectSocket(0, socket, host, remoteAddress, null, context); } @Test public void testSSLTrustVerificationOverride() throws Exception { final SSLContext serverSSLContext = SSLContexts.custom() .useProtocol("TLS") .loadTrustMaterial(keystore) .loadKeyMaterial(keystore, "nopassword".toCharArray()) .build(); this.localServer = new LocalTestServer(serverSSLContext); this.localServer.registerDefaultHandlers(); this.localServer.start(); final HttpHost host = new HttpHost("localhost", 443, "https"); final HttpContext context = new BasicHttpContext(); final TrustStrategy trustStrategy = new TrustStrategy() { public boolean isTrusted( final X509Certificate[] chain, final String authType) throws CertificateException { return chain.length == 1; } }; final SSLContext sslcontext = SSLContexts.custom() .loadTrustMaterial(null, trustStrategy) .build(); final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( sslcontext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); final Socket socket = socketFactory.createSocket(context); final InetSocketAddress remoteAddress = this.localServer.getServiceAddress(); socketFactory.connectSocket(0, socket, host, remoteAddress, null, context); } @Test public void testDefaultHostnameVerifier() throws Exception { final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( SSLContexts.createDefault(), null); Assert.assertNotNull(socketFactory.getHostnameVerifier()); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/util/0040755 0000000 0000000 00000000000 12301751653 026365 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/util/TestInetAddressUtils.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/conn/util/TestInetAddressUtils.0100644 0000000 0000000 00000011203 12301751653 032446 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.conn.util; import org.junit.Assert; import org.junit.Test; /** * Unit tests for InetAddressUtils. */ public class TestInetAddressUtils { @Test public void testValidIPv4Address() { Assert.assertTrue(InetAddressUtils.isIPv4Address("127.0.0.1")); Assert.assertTrue(InetAddressUtils.isIPv4Address("192.168.0.0")); Assert.assertTrue(InetAddressUtils.isIPv4Address("255.255.255.255")); } @Test public void testInvalidIPv4Address() { Assert.assertFalse(InetAddressUtils.isIPv4Address(" 127.0.0.1 ")); // Blanks not allowed Assert.assertFalse(InetAddressUtils.isIPv4Address("g.ar.ba.ge")); Assert.assertFalse(InetAddressUtils.isIPv4Address("192.168.0")); Assert.assertFalse(InetAddressUtils.isIPv4Address("256.255.255.255")); } @Test public void testValidIPv6Address() { Assert.assertTrue(InetAddressUtils.isIPv6StdAddress("2001:0db8:0000:0000:0000:0000:1428:57ab")); Assert.assertTrue(InetAddressUtils.isIPv6StdAddress("2001:db8:0:0:0:0:1428:57ab")); Assert.assertTrue(InetAddressUtils.isIPv6StdAddress("0:0:0:0:0:0:0:0")); Assert.assertTrue(InetAddressUtils.isIPv6HexCompressedAddress("2001:0db8:0:0::1428:57ab")); Assert.assertTrue(InetAddressUtils.isIPv6HexCompressedAddress("2001:0db8::1428:57ab")); Assert.assertTrue(InetAddressUtils.isIPv6HexCompressedAddress("2001:db8::1428:57ab")); Assert.assertTrue(InetAddressUtils.isIPv6HexCompressedAddress("::1")); Assert.assertTrue(InetAddressUtils.isIPv6HexCompressedAddress("::")); // http://tools.ietf.org/html/rfc4291#section-2.2 } @Test public void testInvalidIPv6Address() { Assert.assertFalse(InetAddressUtils.isIPv6Address("2001:0db8:0000:garb:age0:0000:1428:57ab")); Assert.assertFalse(InetAddressUtils.isIPv6Address("2001:0gb8:0000:0000:0000:0000:1428:57ab")); Assert.assertFalse(InetAddressUtils.isIPv6StdAddress("0:0:0:0:0:0:0:0:0")); // Too many Assert.assertFalse(InetAddressUtils.isIPv6StdAddress("0:0:0:0:0:0:0")); // Too few Assert.assertFalse(InetAddressUtils.isIPv6HexCompressedAddress(":1")); Assert.assertFalse(InetAddressUtils.isIPv6Address("2001:0db8::0000::57ab")); // Cannot have two contractions Assert.assertFalse(InetAddressUtils.isIPv6HexCompressedAddress("1:2:3:4:5:6:7::9")); // too many fields before :: Assert.assertFalse(InetAddressUtils.isIPv6HexCompressedAddress("1::3:4:5:6:7:8:9")); // too many fields after :: Assert.assertFalse(InetAddressUtils.isIPv6HexCompressedAddress("::3:4:5:6:7:8:9")); // too many fields after :: } @Test // Test HTTPCLIENT-1319 public void testInvalidIPv6AddressIncorrectGroupCount() { Assert.assertFalse(InetAddressUtils.isIPv6HexCompressedAddress("1:2::4:5:6:7:8:9")); // too many fields in total Assert.assertFalse(InetAddressUtils.isIPv6HexCompressedAddress("1:2:3:4:5:6::8:9")); // too many fields in total } @Test public void testValidIPv4MappedIPv6Address() { Assert.assertTrue(InetAddressUtils.isIPv4MappedIPv64Address("::FFFF:1.2.3.4")); Assert.assertTrue(InetAddressUtils.isIPv4MappedIPv64Address("::ffff:255.255.255.255")); } @Test public void testInValidIPv4MappedIPv6Address() { Assert.assertFalse(InetAddressUtils.isIPv4MappedIPv64Address("2001:0db8:0000:0000:0000:0000:1428:57ab")); Assert.assertFalse(InetAddressUtils.isIPv4MappedIPv64Address("::ffff:1:2:3:4")); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/cookie/0040755 0000000 0000000 00000000000 12301751653 025724 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/cookie/TestCookieOrigin.java0100644 0000000 0000000 00000005130 12301751653 032004 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; import org.junit.Assert; import org.junit.Test; /** * Test cases for {@link CookieOrigin}. */ public class TestCookieOrigin { @Test public void testConstructor() { final CookieOrigin origin = new CookieOrigin("www.apache.org", 80, "/", false); Assert.assertEquals("www.apache.org", origin.getHost()); Assert.assertEquals(80, origin.getPort()); Assert.assertEquals("/", origin.getPath()); Assert.assertFalse(origin.isSecure()); } @Test(expected=IllegalArgumentException.class) public void testNullHost() { new CookieOrigin(null, 80, "/", false); } @Test(expected=IllegalArgumentException.class) public void testEmptyHost() { new CookieOrigin(" ", 80, "/", false); } @Test(expected=IllegalArgumentException.class) public void testNegativePort() { new CookieOrigin("www.apache.org", -80, "/", false); } @Test(expected=IllegalArgumentException.class) public void testNullPath() { new CookieOrigin("www.apache.org", 80, null, false); } @Test public void testEmptyPath() { final CookieOrigin origin = new CookieOrigin("www.apache.org", 80, "", false); Assert.assertEquals("www.apache.org", origin.getHost()); Assert.assertEquals(80, origin.getPort()); Assert.assertEquals("/", origin.getPath()); Assert.assertFalse(origin.isSecure()); } } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/cookie/TestCookiePathComparator.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/cookie/TestCookiePathComparator0100644 0000000 0000000 00000010505 12301751653 032563 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.cookie; import java.util.Comparator; import org.apache.http.impl.cookie.BasicClientCookie; import org.junit.Assert; import org.junit.Test; /** * Test cases for {@link CookiePathComparator}. */ public class TestCookiePathComparator { @Test public void testUnequality1() { final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value"); cookie1.setPath("/a/b/"); final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value"); cookie2.setPath("/a/"); final Comparator comparator = new CookiePathComparator(); Assert.assertTrue(comparator.compare(cookie1, cookie2) < 0); Assert.assertTrue(comparator.compare(cookie2, cookie1) > 0); } @Test public void testUnequality2() { final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value"); cookie1.setPath("/a/b"); final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value"); cookie2.setPath("/a"); final Comparator comparator = new CookiePathComparator(); Assert.assertTrue(comparator.compare(cookie1, cookie2) < 0); Assert.assertTrue(comparator.compare(cookie2, cookie1) > 0); } @Test public void testEquality1() { final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value"); cookie1.setPath("/a"); final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value"); cookie2.setPath("/a"); final Comparator comparator = new CookiePathComparator(); Assert.assertTrue(comparator.compare(cookie1, cookie2) == 0); Assert.assertTrue(comparator.compare(cookie2, cookie1) == 0); } @Test public void testEquality2() { final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value"); cookie1.setPath("/a/"); final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value"); cookie2.setPath("/a"); final Comparator comparator = new CookiePathComparator(); Assert.assertTrue(comparator.compare(cookie1, cookie2) == 0); Assert.assertTrue(comparator.compare(cookie2, cookie1) == 0); } @Test public void testEquality3() { final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value"); cookie1.setPath(null); final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value"); cookie2.setPath("/"); final Comparator comparator = new CookiePathComparator(); Assert.assertTrue(comparator.compare(cookie1, cookie2) == 0); Assert.assertTrue(comparator.compare(cookie2, cookie1) == 0); } @Test public void testEquality4() { final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value"); cookie1.setPath("/this"); final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value"); cookie2.setPath("/that"); final Comparator comparator = new CookiePathComparator(); Assert.assertTrue(comparator.compare(cookie1, cookie2) == 0); Assert.assertTrue(comparator.compare(cookie2, cookie1) == 0); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/0040755 0000000 0000000 00000000000 12301751657 025420 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/auth/0040755 0000000 0000000 00000000000 12301751657 026361 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/auth/TestBasicScheme.java0100644 0000000 0000000 00000012137 12301751657 032233 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import org.apache.commons.codec.binary.Base64; import org.apache.http.Consts; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EncodingUtils; import org.junit.Assert; import org.junit.Test; /** * Basic authentication test cases. */ public class TestBasicScheme { @Test(expected=MalformedChallengeException.class) public void testBasicAuthenticationWithNoRealm() throws Exception { final String challenge = "Basic"; final Header header = new BasicHeader(AUTH.WWW_AUTH, challenge); final AuthScheme authscheme = new BasicScheme(); authscheme.processChallenge(header); } @Test public void testBasicAuthenticationWith88591Chars() throws Exception { final int[] germanChars = { 0xE4, 0x2D, 0xF6, 0x2D, 0xFc }; final StringBuilder buffer = new StringBuilder(); for (final int germanChar : germanChars) { buffer.append((char)germanChar); } final UsernamePasswordCredentials creds = new UsernamePasswordCredentials("dh", buffer.toString()); final BasicScheme authscheme = new BasicScheme(Consts.ISO_8859_1); final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpContext context = new BasicHttpContext(); final Header header = authscheme.authenticate(creds, request, context); Assert.assertEquals("Basic ZGg65C32Lfw=", header.getValue()); } @Test public void testBasicAuthentication() throws Exception { final UsernamePasswordCredentials creds = new UsernamePasswordCredentials("testuser", "testpass"); final Header challenge = new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"test\""); final BasicScheme authscheme = new BasicScheme(); authscheme.processChallenge(challenge); final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpContext context = new BasicHttpContext(); final Header authResponse = authscheme.authenticate(creds, request, context); final String expected = "Basic " + EncodingUtils.getAsciiString( Base64.encodeBase64(EncodingUtils.getAsciiBytes("testuser:testpass"))); Assert.assertEquals(AUTH.WWW_AUTH_RESP, authResponse.getName()); Assert.assertEquals(expected, authResponse.getValue()); Assert.assertEquals("test", authscheme.getRealm()); Assert.assertTrue(authscheme.isComplete()); Assert.assertFalse(authscheme.isConnectionBased()); } @Test public void testBasicProxyAuthentication() throws Exception { final UsernamePasswordCredentials creds = new UsernamePasswordCredentials("testuser", "testpass"); final Header challenge = new BasicHeader(AUTH.PROXY_AUTH, "Basic realm=\"test\""); final BasicScheme authscheme = new BasicScheme(); authscheme.processChallenge(challenge); final HttpRequest request = new BasicHttpRequest("GET", "/"); final HttpContext context = new BasicHttpContext(); final Header authResponse = authscheme.authenticate(creds, request, context); final String expected = "Basic " + EncodingUtils.getAsciiString( Base64.encodeBase64(EncodingUtils.getAsciiBytes("testuser:testpass"))); Assert.assertEquals(AUTH.PROXY_AUTH_RESP, authResponse.getName()); Assert.assertEquals(expected, authResponse.getValue()); Assert.assertEquals("test", authscheme.getRealm()); Assert.assertTrue(authscheme.isComplete()); Assert.assertFalse(authscheme.isConnectionBased()); } } ././@LongLink0100644 0000000 0000000 00000000145 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/auth/TestDigestScheme.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/auth/TestDigestScheme.java0100644 0000000 0000000 00000074662 12301751657 032444 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.MessageDigest; import java.util.HashMap; import java.util.Map; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.Credentials; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHeaderValueParser; import org.apache.http.message.BasicHttpEntityEnclosingRequest; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.junit.Assert; import org.junit.Test; /** * Test Methods for DigestScheme Authentication. */ public class TestDigestScheme { @Test(expected=MalformedChallengeException.class) public void testDigestAuthenticationEmptyChallenge1() throws Exception { final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, "Digest"); final AuthScheme authscheme = new DigestScheme(); authscheme.processChallenge(authChallenge); } @Test(expected=MalformedChallengeException.class) public void testDigestAuthenticationEmptyChallenge2() throws Exception { final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, "Digest "); final AuthScheme authscheme = new DigestScheme(); authscheme.processChallenge(authChallenge); } @Test public void testDigestAuthenticationWithDefaultCreds() throws Exception { final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\""; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final HttpRequest request = new BasicHttpRequest("Simple", "/"); final Credentials cred = new UsernamePasswordCredentials("username","password"); final DigestScheme authscheme = new DigestScheme(); final HttpContext context = new BasicHttpContext(); authscheme.processChallenge(authChallenge); final Header authResponse = authscheme.authenticate(cred, request, context); Assert.assertTrue(authscheme.isComplete()); Assert.assertFalse(authscheme.isConnectionBased()); final Map table = parseAuthResponse(authResponse); Assert.assertEquals("username", table.get("username")); Assert.assertEquals("realm1", table.get("realm")); Assert.assertEquals("/", table.get("uri")); Assert.assertEquals("f2a3f18799759d4f1a1c068b92b573cb", table.get("nonce")); Assert.assertEquals("e95a7ddf37c2eab009568b1ed134f89a", table.get("response")); } @Test public void testDigestAuthentication() throws Exception { final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\""; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final HttpRequest request = new BasicHttpRequest("Simple", "/"); final Credentials cred = new UsernamePasswordCredentials("username","password"); final DigestScheme authscheme = new DigestScheme(); final HttpContext context = new BasicHttpContext(); authscheme.processChallenge(authChallenge); final Header authResponse = authscheme.authenticate(cred, request, context); final Map table = parseAuthResponse(authResponse); Assert.assertEquals("username", table.get("username")); Assert.assertEquals("realm1", table.get("realm")); Assert.assertEquals("/", table.get("uri")); Assert.assertEquals("f2a3f18799759d4f1a1c068b92b573cb", table.get("nonce")); Assert.assertEquals("e95a7ddf37c2eab009568b1ed134f89a", table.get("response")); } @Test public void testDigestAuthenticationInvalidInput() throws Exception { final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\""; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final HttpRequest request = new BasicHttpRequest("Simple", "/"); final Credentials cred = new UsernamePasswordCredentials("username","password"); final DigestScheme authscheme = new DigestScheme(); final HttpContext context = new BasicHttpContext(); authscheme.processChallenge(authChallenge); try { authscheme.authenticate(null, request, context); Assert.fail("IllegalArgumentException should have been thrown"); } catch (final IllegalArgumentException ex) { } try { authscheme.authenticate(cred, null, context); Assert.fail("IllegalArgumentException should have been thrown"); } catch (final IllegalArgumentException ex) { } } @Test public void testDigestAuthenticationOverrideParameter() throws Exception { final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\""; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final HttpRequest request = new BasicHttpRequest("Simple", "/"); final Credentials cred = new UsernamePasswordCredentials("username","password"); final DigestScheme authscheme = new DigestScheme(); final HttpContext context = new BasicHttpContext(); authscheme.processChallenge(authChallenge); authscheme.overrideParamter("realm", "other realm"); final Header authResponse = authscheme.authenticate(cred, request, context); final Map table = parseAuthResponse(authResponse); Assert.assertEquals("username", table.get("username")); Assert.assertEquals("other realm", table.get("realm")); Assert.assertEquals("/", table.get("uri")); Assert.assertEquals("f2a3f18799759d4f1a1c068b92b573cb", table.get("nonce")); Assert.assertEquals("3f211de10463cbd055ab4cd9c5158eac", table.get("response")); } @Test public void testDigestAuthenticationWithSHA() throws Exception { final String challenge = "Digest realm=\"realm1\", " + "nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", " + "algorithm=SHA"; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final HttpRequest request = new BasicHttpRequest("Simple", "/"); final Credentials cred = new UsernamePasswordCredentials("username","password"); final HttpContext context = new BasicHttpContext(); final DigestScheme authscheme = new DigestScheme(); authscheme.processChallenge(authChallenge); final Header authResponse = authscheme.authenticate(cred, request, context); final Map table = parseAuthResponse(authResponse); Assert.assertEquals("username", table.get("username")); Assert.assertEquals("realm1", table.get("realm")); Assert.assertEquals("/", table.get("uri")); Assert.assertEquals("f2a3f18799759d4f1a1c068b92b573cb", table.get("nonce")); Assert.assertEquals("8769e82e4e28ecc040b969562b9050580c6d186d", table.get("response")); } @Test public void testDigestAuthenticationWithQueryStringInDigestURI() throws Exception { final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\""; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final HttpRequest request = new BasicHttpRequest("Simple", "/?param=value"); final Credentials cred = new UsernamePasswordCredentials("username","password"); final HttpContext context = new BasicHttpContext(); final DigestScheme authscheme = new DigestScheme(); authscheme.processChallenge(authChallenge); final Header authResponse = authscheme.authenticate(cred, request, context); final Map table = parseAuthResponse(authResponse); Assert.assertEquals("username", table.get("username")); Assert.assertEquals("realm1", table.get("realm")); Assert.assertEquals("/?param=value", table.get("uri")); Assert.assertEquals("f2a3f18799759d4f1a1c068b92b573cb", table.get("nonce")); Assert.assertEquals("a847f58f5fef0bc087bcb9c3eb30e042", table.get("response")); } @Test public void testDigestAuthenticationWithMultipleRealms() throws Exception { final String challenge1 = "Digest realm=\"realm1\", nonce=\"abcde\""; final String challenge2 = "Digest realm=\"realm2\", nonce=\"123546\""; final Credentials cred = new UsernamePasswordCredentials("username","password"); final Credentials cred2 = new UsernamePasswordCredentials("uname2","password2"); Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge1); final HttpRequest request = new BasicHttpRequest("Simple", "/"); final HttpContext context = new BasicHttpContext(); final DigestScheme authscheme = new DigestScheme(); authscheme.processChallenge(authChallenge); Header authResponse = authscheme.authenticate(cred, request, context); Map table = parseAuthResponse(authResponse); Assert.assertEquals("username", table.get("username")); Assert.assertEquals("realm1", table.get("realm")); Assert.assertEquals("/", table.get("uri")); Assert.assertEquals("abcde", table.get("nonce")); Assert.assertEquals("786f500303eac1478f3c2865e676ed68", table.get("response")); authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge2); final DigestScheme authscheme2 = new DigestScheme(); authscheme2.processChallenge(authChallenge); authResponse = authscheme2.authenticate(cred2, request, context); table = parseAuthResponse(authResponse); Assert.assertEquals("uname2", table.get("username")); Assert.assertEquals("realm2", table.get("realm")); Assert.assertEquals("/", table.get("uri")); Assert.assertEquals("123546", table.get("nonce")); Assert.assertEquals("0283edd9ef06a38b378b3b74661391e9", table.get("response")); } @Test(expected=AuthenticationException.class) public void testDigestAuthenticationNoRealm() throws Exception { final String challenge = "Digest no-realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\""; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final HttpContext context = new BasicHttpContext(); final DigestScheme authscheme = new DigestScheme(); authscheme.processChallenge(authChallenge); final Credentials cred = new UsernamePasswordCredentials("username","password"); final HttpRequest request = new BasicHttpRequest("Simple", "/"); authscheme.authenticate(cred, request, context); } @Test(expected=AuthenticationException.class) public void testDigestAuthenticationNoNonce() throws Exception { final String challenge = "Digest realm=\"realm1\", no-nonce=\"f2a3f18799759d4f1a1c068b92b573cb\""; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final HttpContext context = new BasicHttpContext(); final DigestScheme authscheme = new DigestScheme(); authscheme.processChallenge(authChallenge); final Credentials cred = new UsernamePasswordCredentials("username","password"); final HttpRequest request = new BasicHttpRequest("Simple", "/"); authscheme.authenticate(cred, request, context); } /** * Test digest authentication using the MD5-sess algorithm. */ @Test public void testDigestAuthenticationMD5Sess() throws Exception { // Example using Digest auth with MD5-sess final String realm="realm"; final String username="username"; final String password="password"; final String nonce="e273f1776275974f1a120d8b92c5b3cb"; final String challenge="Digest realm=\"" + realm + "\", " + "nonce=\"" + nonce + "\", " + "opaque=\"SomeString\", " + "stale=false, " + "algorithm=MD5-sess, " + "qop=\"auth,auth-int\""; // we pass both but expect auth to be used final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final Credentials cred = new UsernamePasswordCredentials(username, password); final HttpRequest request = new BasicHttpRequest("Simple", "/"); final HttpContext context = new BasicHttpContext(); final DigestScheme authscheme = new DigestScheme(); authscheme.processChallenge(authChallenge); final Header authResponse = authscheme.authenticate(cred, request, context); final String response = authResponse.getValue(); Assert.assertTrue(response.indexOf("nc=00000001") > 0); // test for quotes Assert.assertTrue(response.indexOf("qop=auth") > 0); // test for quotes final Map table = parseAuthResponse(authResponse); Assert.assertEquals(username, table.get("username")); Assert.assertEquals(realm, table.get("realm")); Assert.assertEquals("MD5-sess", table.get("algorithm")); Assert.assertEquals("/", table.get("uri")); Assert.assertEquals(nonce, table.get("nonce")); Assert.assertEquals(1, Integer.parseInt(table.get("nc"),16)); Assert.assertTrue(null != table.get("cnonce")); Assert.assertEquals("SomeString", table.get("opaque")); Assert.assertEquals("auth", table.get("qop")); //@TODO: add better check Assert.assertTrue(null != table.get("response")); } /** * Test digest authentication using the MD5-sess algorithm. */ @Test public void testDigestAuthenticationMD5SessNoQop() throws Exception { // Example using Digest auth with MD5-sess final String realm="realm"; final String username="username"; final String password="password"; final String nonce="e273f1776275974f1a120d8b92c5b3cb"; final String challenge="Digest realm=\"" + realm + "\", " + "nonce=\"" + nonce + "\", " + "opaque=\"SomeString\", " + "stale=false, " + "algorithm=MD5-sess"; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final Credentials cred = new UsernamePasswordCredentials(username, password); final HttpRequest request = new BasicHttpRequest("Simple", "/"); final HttpContext context = new BasicHttpContext(); final DigestScheme authscheme = new DigestScheme(); authscheme.processChallenge(authChallenge); final Header authResponse = authscheme.authenticate(cred, request, context); final Map table = parseAuthResponse(authResponse); Assert.assertEquals(username, table.get("username")); Assert.assertEquals(realm, table.get("realm")); Assert.assertEquals("MD5-sess", table.get("algorithm")); Assert.assertEquals("/", table.get("uri")); Assert.assertEquals(nonce, table.get("nonce")); Assert.assertTrue(null == table.get("nc")); Assert.assertEquals("SomeString", table.get("opaque")); Assert.assertTrue(null == table.get("qop")); //@TODO: add better check Assert.assertTrue(null != table.get("response")); } /** * Test digest authentication with unknown qop value */ @Test(expected=AuthenticationException.class) public void testDigestAuthenticationMD5SessUnknownQop() throws Exception { // Example using Digest auth with MD5-sess final String realm="realm"; final String username="username"; final String password="password"; final String nonce="e273f1776275974f1a120d8b92c5b3cb"; final String challenge="Digest realm=\"" + realm + "\", " + "nonce=\"" + nonce + "\", " + "opaque=\"SomeString\", " + "stale=false, " + "algorithm=MD5-sess, " + "qop=\"stuff\""; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final DigestScheme authscheme = new DigestScheme(); authscheme.processChallenge(authChallenge); final Credentials cred = new UsernamePasswordCredentials(username, password); final HttpRequest request = new BasicHttpRequest("Simple", "/"); final HttpContext context = new BasicHttpContext(); authscheme.authenticate(cred, request, context); } /** * Test digest authentication with unknown qop value */ @Test(expected=AuthenticationException.class) public void testDigestAuthenticationUnknownAlgo() throws Exception { // Example using Digest auth with MD5-sess final String realm="realm"; final String username="username"; final String password="password"; final String nonce="e273f1776275974f1a120d8b92c5b3cb"; final String challenge="Digest realm=\"" + realm + "\", " + "nonce=\"" + nonce + "\", " + "opaque=\"SomeString\", " + "stale=false, " + "algorithm=stuff, " + "qop=\"auth\""; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final DigestScheme authscheme = new DigestScheme(); authscheme.processChallenge(authChallenge); final Credentials cred = new UsernamePasswordCredentials(username, password); final HttpRequest request = new BasicHttpRequest("Simple", "/"); final HttpContext context = new BasicHttpContext(); authscheme.authenticate(cred, request, context); } @Test public void testDigestAuthenticationWithStaleNonce() throws Exception { final String challenge = "Digest realm=\"realm1\", " + "nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", stale=\"true\""; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final AuthScheme authscheme = new DigestScheme(); authscheme.processChallenge(authChallenge); Assert.assertFalse(authscheme.isComplete()); } private static Map parseAuthResponse(final Header authResponse) { final String s = authResponse.getValue(); if (!s.startsWith("Digest ")) { return null; } final HeaderElement[] elements = BasicHeaderValueParser.parseElements(s.substring(7), null); final Map map = new HashMap(elements.length); for (final HeaderElement element : elements) { map.put(element.getName(), element.getValue()); } return map; } @Test public void testDigestNouceCount() throws Exception { final String challenge1 = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", qop=auth"; final Header authChallenge1 = new BasicHeader(AUTH.WWW_AUTH, challenge1); final HttpRequest request = new BasicHttpRequest("GET", "/"); final Credentials cred = new UsernamePasswordCredentials("username","password"); final HttpContext context = new BasicHttpContext(); final DigestScheme authscheme = new DigestScheme(); authscheme.processChallenge(authChallenge1); final Header authResponse1 = authscheme.authenticate(cred, request, context); final Map table1 = parseAuthResponse(authResponse1); Assert.assertEquals("00000001", table1.get("nc")); final Header authResponse2 = authscheme.authenticate(cred, request, context); final Map table2 = parseAuthResponse(authResponse2); Assert.assertEquals("00000002", table2.get("nc")); final String challenge2 = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", qop=auth"; final Header authChallenge2 = new BasicHeader(AUTH.WWW_AUTH, challenge2); authscheme.processChallenge(authChallenge2); final Header authResponse3 = authscheme.authenticate(cred, request, context); final Map table3 = parseAuthResponse(authResponse3); Assert.assertEquals("00000003", table3.get("nc")); final String challenge3 = "Digest realm=\"realm1\", nonce=\"e273f1776275974f1a120d8b92c5b3cb\", qop=auth"; final Header authChallenge3 = new BasicHeader(AUTH.WWW_AUTH, challenge3); authscheme.processChallenge(authChallenge3); final Header authResponse4 = authscheme.authenticate(cred, request, context); final Map table4 = parseAuthResponse(authResponse4); Assert.assertEquals("00000001", table4.get("nc")); } @Test public void testDigestMD5SessA1AndCnonceConsistency() throws Exception { final String challenge1 = "Digest qop=\"auth\", algorithm=MD5-sess, nonce=\"1234567890abcdef\", " + "charset=utf-8, realm=\"subnet.domain.com\""; final Header authChallenge1 = new BasicHeader(AUTH.WWW_AUTH, challenge1); final HttpRequest request = new BasicHttpRequest("GET", "/"); final Credentials cred = new UsernamePasswordCredentials("username","password"); final HttpContext context = new BasicHttpContext(); final DigestScheme authscheme = new DigestScheme(); authscheme.processChallenge(authChallenge1); final Header authResponse1 = authscheme.authenticate(cred, request, context); final Map table1 = parseAuthResponse(authResponse1); Assert.assertEquals("00000001", table1.get("nc")); final String cnonce1 = authscheme.getCnonce(); final String sessionKey1 = authscheme.getA1(); final Header authResponse2 = authscheme.authenticate(cred, request, context); final Map table2 = parseAuthResponse(authResponse2); Assert.assertEquals("00000002", table2.get("nc")); final String cnonce2 = authscheme.getCnonce(); final String sessionKey2 = authscheme.getA1(); Assert.assertEquals(cnonce1, cnonce2); Assert.assertEquals(sessionKey1, sessionKey2); final String challenge2 = "Digest qop=\"auth\", algorithm=MD5-sess, nonce=\"1234567890abcdef\", " + "charset=utf-8, realm=\"subnet.domain.com\""; final Header authChallenge2 = new BasicHeader(AUTH.WWW_AUTH, challenge2); authscheme.processChallenge(authChallenge2); final Header authResponse3 = authscheme.authenticate(cred, request, context); final Map table3 = parseAuthResponse(authResponse3); Assert.assertEquals("00000003", table3.get("nc")); final String cnonce3 = authscheme.getCnonce(); final String sessionKey3 = authscheme.getA1(); Assert.assertEquals(cnonce1, cnonce3); Assert.assertEquals(sessionKey1, sessionKey3); final String challenge3 = "Digest qop=\"auth\", algorithm=MD5-sess, nonce=\"fedcba0987654321\", " + "charset=utf-8, realm=\"subnet.domain.com\""; final Header authChallenge3 = new BasicHeader(AUTH.WWW_AUTH, challenge3); authscheme.processChallenge(authChallenge3); final Header authResponse4 = authscheme.authenticate(cred, request, context); final Map table4 = parseAuthResponse(authResponse4); Assert.assertEquals("00000001", table4.get("nc")); final String cnonce4 = authscheme.getCnonce(); final String sessionKey4 = authscheme.getA1(); Assert.assertFalse(cnonce1.equals(cnonce4)); Assert.assertFalse(sessionKey1.equals(sessionKey4)); } @Test public void testHttpEntityDigest() throws Exception { final HttpEntityDigester digester = new HttpEntityDigester(MessageDigest.getInstance("MD5")); Assert.assertNull(digester.getDigest()); digester.write('a'); digester.write('b'); digester.write('c'); digester.write(0xe4); digester.write(0xf6); digester.write(0xfc); digester.write(new byte[] { 'a', 'b', 'c'}); Assert.assertNull(digester.getDigest()); digester.close(); Assert.assertEquals("acd2b59cd01c7737d8069015584c6cac", DigestScheme.encode(digester.getDigest())); try { digester.write('a'); Assert.fail("IOException should have been thrown"); } catch (final IOException ex) { } try { digester.write(new byte[] { 'a', 'b', 'c'}); Assert.fail("IOException should have been thrown"); } catch (final IOException ex) { } } @Test public void testDigestAuthenticationQopAuthInt() throws Exception { final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", " + "qop=\"auth,auth-int\""; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("Post", "/"); request.setEntity(new StringEntity("abc\u00e4\u00f6\u00fcabc", HTTP.DEF_CONTENT_CHARSET)); final Credentials cred = new UsernamePasswordCredentials("username","password"); final DigestScheme authscheme = new DigestScheme(); final HttpContext context = new BasicHttpContext(); authscheme.processChallenge(authChallenge); final Header authResponse = authscheme.authenticate(cred, request, context); Assert.assertEquals("Post:/:acd2b59cd01c7737d8069015584c6cac", authscheme.getA2()); final Map table = parseAuthResponse(authResponse); Assert.assertEquals("username", table.get("username")); Assert.assertEquals("realm1", table.get("realm")); Assert.assertEquals("/", table.get("uri")); Assert.assertEquals("auth-int", table.get("qop")); Assert.assertEquals("f2a3f18799759d4f1a1c068b92b573cb", table.get("nonce")); } @Test public void testDigestAuthenticationQopAuthIntNullEntity() throws Exception { final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", " + "qop=\"auth,auth-int\""; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final HttpRequest request = new BasicHttpEntityEnclosingRequest("Post", "/"); final Credentials cred = new UsernamePasswordCredentials("username","password"); final DigestScheme authscheme = new DigestScheme(); final HttpContext context = new BasicHttpContext(); authscheme.processChallenge(authChallenge); final Header authResponse = authscheme.authenticate(cred, request, context); Assert.assertEquals("Post:/:d41d8cd98f00b204e9800998ecf8427e", authscheme.getA2()); final Map table = parseAuthResponse(authResponse); Assert.assertEquals("username", table.get("username")); Assert.assertEquals("realm1", table.get("realm")); Assert.assertEquals("/", table.get("uri")); Assert.assertEquals("auth-int", table.get("qop")); Assert.assertEquals("f2a3f18799759d4f1a1c068b92b573cb", table.get("nonce")); } @Test public void testDigestAuthenticationQopAuthOrAuthIntNonRepeatableEntity() throws Exception { final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", " + "qop=\"auth,auth-int\""; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("Post", "/"); request.setEntity(new InputStreamEntity(new ByteArrayInputStream(new byte[] {'a'}), -1)); final Credentials cred = new UsernamePasswordCredentials("username","password"); final DigestScheme authscheme = new DigestScheme(); final HttpContext context = new BasicHttpContext(); authscheme.processChallenge(authChallenge); final Header authResponse = authscheme.authenticate(cred, request, context); Assert.assertEquals("Post:/", authscheme.getA2()); final Map table = parseAuthResponse(authResponse); Assert.assertEquals("username", table.get("username")); Assert.assertEquals("realm1", table.get("realm")); Assert.assertEquals("/", table.get("uri")); Assert.assertEquals("auth", table.get("qop")); Assert.assertEquals("f2a3f18799759d4f1a1c068b92b573cb", table.get("nonce")); } @Test(expected=AuthenticationException.class) public void testDigestAuthenticationQopIntOnlyNonRepeatableEntity() throws Exception { final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", " + "qop=\"auth-int\""; final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("Post", "/"); request.setEntity(new InputStreamEntity(new ByteArrayInputStream(new byte[] {'a'}), -1)); final Credentials cred = new UsernamePasswordCredentials("username","password"); final DigestScheme authscheme = new DigestScheme(); final HttpContext context = new BasicHttpContext(); authscheme.processChallenge(authChallenge); authscheme.authenticate(cred, request, context); } } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/auth/TestHttpAuthenticator.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/auth/TestHttpAuthenticator0100644 0000000 0000000 00000061071 12301751657 032620 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import java.util.HashMap; import java.util.LinkedList; import java.util.Queue; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthOption; import org.apache.http.auth.AuthProtocolState; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthState; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.ContextAwareAuthScheme; import org.apache.http.auth.Credentials; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.client.AuthCache; import org.apache.http.client.AuthenticationStrategy; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.Lookup; import org.apache.http.config.RegistryBuilder; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.TargetAuthenticationStrategy; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpRequest; import org.apache.http.message.BasicHttpResponse; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpCoreContext; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; public class TestHttpAuthenticator { private AuthenticationStrategy authStrategy; private AuthState authState; private ContextAwareAuthScheme authScheme; private HttpContext context; private HttpHost host; private Credentials credentials; private BasicCredentialsProvider credentialsProvider; private Lookup authSchemeRegistry; private AuthCache authCache; private HttpAuthenticator httpAuthenticator; @Before public void setUp() throws Exception { this.authStrategy = Mockito.mock(AuthenticationStrategy.class); this.authState = new AuthState(); this.authScheme = Mockito.mock(ContextAwareAuthScheme.class); Mockito.when(this.authScheme.getSchemeName()).thenReturn("Basic"); Mockito.when(this.authScheme.isComplete()).thenReturn(Boolean.TRUE); this.context = new BasicHttpContext(); this.host = new HttpHost("localhost", 80); this.context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.host); this.credentials = Mockito.mock(Credentials.class); this.credentialsProvider = new BasicCredentialsProvider(); this.credentialsProvider.setCredentials(AuthScope.ANY, this.credentials); this.context.setAttribute(HttpClientContext.CREDS_PROVIDER, this.credentialsProvider); this.authSchemeRegistry = RegistryBuilder.create() .register("basic", new BasicSchemeFactory()) .register("digest", new DigestSchemeFactory()) .register("ntlm", new NTLMSchemeFactory()).build(); this.context.setAttribute(HttpClientContext.AUTHSCHEME_REGISTRY, this.authSchemeRegistry); this.authCache = Mockito.mock(AuthCache.class); this.context.setAttribute(HttpClientContext.AUTH_CACHE, this.authCache); this.httpAuthenticator = new HttpAuthenticator(); } @Test public void testAuthenticationRequested() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); Mockito.when(this.authStrategy.isAuthenticationRequested( Mockito.any(HttpHost.class), Mockito.any(HttpResponse.class), Mockito.any(HttpContext.class))).thenReturn(Boolean.TRUE); Assert.assertTrue(this.httpAuthenticator.isAuthenticationRequested( this.host, response, this.authStrategy, this.authState, this.context)); Mockito.verify(this.authStrategy).isAuthenticationRequested(this.host, response, this.context); } @Test public void testAuthenticationRequestedAfterSuccess() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); Mockito.when(this.authStrategy.isAuthenticationRequested( Mockito.any(HttpHost.class), Mockito.any(HttpResponse.class), Mockito.any(HttpContext.class))).thenReturn(Boolean.TRUE); this.authState.update(this.authScheme, this.credentials); this.authState.setState(AuthProtocolState.SUCCESS); Assert.assertTrue(this.httpAuthenticator.isAuthenticationRequested( this.host, response, this.authStrategy, this.authState, this.context)); Mockito.verify(this.authStrategy).isAuthenticationRequested(this.host, response, this.context); Mockito.verify(this.authStrategy).authFailed(this.host, this.authScheme, this.context); } @Test public void testAuthenticationNotRequestedUnchallenged() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); Mockito.when(this.authStrategy.isAuthenticationRequested( Mockito.any(HttpHost.class), Mockito.any(HttpResponse.class), Mockito.any(HttpContext.class))).thenReturn(Boolean.FALSE); Assert.assertFalse(this.httpAuthenticator.isAuthenticationRequested( this.host, response, this.authStrategy, this.authState, this.context)); Assert.assertEquals(AuthProtocolState.UNCHALLENGED, this.authState.getState()); Mockito.verify(this.authStrategy).isAuthenticationRequested(this.host, response, this.context); } @Test public void testAuthenticationNotRequestedSuccess1() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); Mockito.when(this.authStrategy.isAuthenticationRequested( Mockito.any(HttpHost.class), Mockito.any(HttpResponse.class), Mockito.any(HttpContext.class))).thenReturn(Boolean.FALSE); this.authState.update(this.authScheme, this.credentials); this.authState.setState(AuthProtocolState.CHALLENGED); Assert.assertFalse(this.httpAuthenticator.isAuthenticationRequested( this.host, response, this.authStrategy, this.authState, this.context)); Assert.assertEquals(AuthProtocolState.SUCCESS, this.authState.getState()); Mockito.verify(this.authStrategy).isAuthenticationRequested(this.host, response, this.context); Mockito.verify(this.authStrategy).authSucceeded(this.host, this.authScheme, this.context); } @Test public void testAuthenticationNotRequestedSuccess2() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); Mockito.when(this.authStrategy.isAuthenticationRequested( Mockito.any(HttpHost.class), Mockito.any(HttpResponse.class), Mockito.any(HttpContext.class))).thenReturn(Boolean.FALSE); this.authState.update(this.authScheme, this.credentials); this.authState.setState(AuthProtocolState.HANDSHAKE); Assert.assertFalse(this.httpAuthenticator.isAuthenticationRequested( this.host, response, this.authStrategy, this.authState, this.context)); Assert.assertEquals(AuthProtocolState.SUCCESS, this.authState.getState()); Mockito.verify(this.authStrategy).isAuthenticationRequested(this.host, response, this.context); Mockito.verify(this.authStrategy).authSucceeded(this.host, this.authScheme, this.context); } @Test public void testAuthentication() throws Exception { final HttpHost host = new HttpHost("somehost", 80); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"test\"")); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\"")); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "whatever realm=\"realm1\", stuff=\"1234\"")); final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); Assert.assertTrue(this.httpAuthenticator.handleAuthChallenge(host, response, authStrategy, this.authState, this.context)); Assert.assertEquals(AuthProtocolState.CHALLENGED, this.authState.getState()); final Queue options = this.authState.getAuthOptions(); Assert.assertNotNull(options); final AuthOption option1 = options.poll(); Assert.assertNotNull(option1); Assert.assertEquals("digest", option1.getAuthScheme().getSchemeName()); final AuthOption option2 = options.poll(); Assert.assertNotNull(option2); Assert.assertEquals("basic", option2.getAuthScheme().getSchemeName()); Assert.assertNull(options.poll()); } @Test public void testAuthenticationNoChallenges() throws Exception { final HttpHost host = new HttpHost("somehost", 80); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); Mockito.when(this.authStrategy.getChallenges( Mockito.any(HttpHost.class), Mockito.any(HttpResponse.class), Mockito.any(HttpContext.class))).thenReturn(new HashMap()); Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(host, response, this.authStrategy, this.authState, this.context)); } @Test public void testAuthenticationNoSupportedChallenges() throws Exception { final HttpHost host = new HttpHost("somehost", 80); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "This realm=\"test\"")); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "That realm=\"realm1\", nonce=\"1234\"")); final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(host, response, authStrategy, this.authState, this.context)); } @Test public void testAuthenticationNoCredentials() throws Exception { final HttpHost host = new HttpHost("somehost", 80); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"test\"")); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\"")); this.credentialsProvider.clear(); final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(host, response, authStrategy, this.authState, this.context)); } @Test public void testAuthenticationFailed() throws Exception { final HttpHost host = new HttpHost("somehost", 80); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"test\"")); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\"")); this.authState.setState(AuthProtocolState.CHALLENGED); this.authState.update(this.authScheme, this.credentials); final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(host, response, authStrategy, this.authState, this.context)); Assert.assertEquals(AuthProtocolState.FAILURE, this.authState.getState()); Mockito.verify(this.authCache).remove(host); } @Test public void testAuthenticationFailedPreviously() throws Exception { final HttpHost host = new HttpHost("somehost", 80); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"test\"")); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\"")); this.authState.setState(AuthProtocolState.FAILURE); final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(host, response, authStrategy, this.authState, this.context)); Assert.assertEquals(AuthProtocolState.FAILURE, this.authState.getState()); } @Test public void testAuthenticationFailure() throws Exception { final HttpHost host = new HttpHost("somehost", 80); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"test\"")); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\"")); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "whatever realm=\"realm1\", stuff=\"1234\"")); final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); this.authState.setState(AuthProtocolState.CHALLENGED); this.authState.update(new BasicScheme(), this.credentials); Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(host, response, authStrategy, this.authState, this.context)); Assert.assertEquals(AuthProtocolState.FAILURE, this.authState.getState()); Assert.assertNull(this.authState.getCredentials()); } @Test public void testAuthenticationHandshaking() throws Exception { final HttpHost host = new HttpHost("somehost", 80); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"test\"")); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", stale=true, nonce=\"1234\"")); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "whatever realm=\"realm1\", stuff=\"1234\"")); final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); this.authState.setState(AuthProtocolState.CHALLENGED); this.authState.update(new DigestScheme(), this.credentials); Assert.assertTrue(this.httpAuthenticator.handleAuthChallenge(host, response, authStrategy, this.authState, this.context)); Assert.assertEquals(AuthProtocolState.HANDSHAKE, this.authState.getState()); } @Test public void testAuthenticationNoMatchingChallenge() throws Exception { final HttpHost host = new HttpHost("somehost", 80); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\"")); response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "whatever realm=\"realm1\", stuff=\"1234\"")); final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); this.authState.setState(AuthProtocolState.CHALLENGED); this.authState.update(new BasicScheme(), this.credentials); Assert.assertTrue(this.httpAuthenticator.handleAuthChallenge(host, response, authStrategy, this.authState, this.context)); Assert.assertEquals(AuthProtocolState.CHALLENGED, this.authState.getState()); final Queue options = this.authState.getAuthOptions(); Assert.assertNotNull(options); final AuthOption option1 = options.poll(); Assert.assertNotNull(option1); Assert.assertEquals("digest", option1.getAuthScheme().getSchemeName()); Assert.assertNull(options.poll()); } @Test public void testAuthenticationException() throws Exception { final HttpHost host = new HttpHost("somehost", 80); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); this.authState.setState(AuthProtocolState.CHALLENGED); Mockito.doThrow(new MalformedChallengeException()).when(this.authStrategy).getChallenges( Mockito.any(HttpHost.class), Mockito.any(HttpResponse.class), Mockito.any(HttpContext.class)); Assert.assertFalse(this.httpAuthenticator.handleAuthChallenge(host, response, this.authStrategy, this.authState, this.context)); Assert.assertEquals(AuthProtocolState.UNCHALLENGED, this.authState.getState()); Assert.assertNull(this.authState.getAuthScheme()); Assert.assertNull(this.authState.getCredentials()); } @Test public void testAuthFailureState() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); this.authState.setState(AuthProtocolState.FAILURE); this.authState.update(this.authScheme, this.credentials); this.httpAuthenticator.generateAuthResponse(request, authState, context); Assert.assertFalse(request.containsHeader(AUTH.WWW_AUTH_RESP)); Mockito.verify(this.authScheme, Mockito.never()).authenticate( Mockito.any(Credentials.class), Mockito.any(HttpRequest.class), Mockito.any(HttpContext.class)); } @Test public void testAuthChallengeStateNoOption() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); this.authState.setState(AuthProtocolState.CHALLENGED); this.authState.update(this.authScheme, this.credentials); Mockito.when(this.authScheme.authenticate( Mockito.any(Credentials.class), Mockito.any(HttpRequest.class), Mockito.any(HttpContext.class))).thenReturn(new BasicHeader(AUTH.WWW_AUTH_RESP, "stuff")); this.httpAuthenticator.generateAuthResponse(request, authState, context); Assert.assertTrue(request.containsHeader(AUTH.WWW_AUTH_RESP)); Mockito.verify(this.authScheme).authenticate(this.credentials, request, this.context); } @Test public void testAuthChallengeStateOneOptions() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); this.authState.setState(AuthProtocolState.CHALLENGED); final LinkedList authOptions = new LinkedList(); authOptions.add(new AuthOption(this.authScheme, this.credentials)); this.authState.update(authOptions); Mockito.when(this.authScheme.authenticate( Mockito.any(Credentials.class), Mockito.any(HttpRequest.class), Mockito.any(HttpContext.class))).thenReturn(new BasicHeader(AUTH.WWW_AUTH_RESP, "stuff")); this.httpAuthenticator.generateAuthResponse(request, authState, context); Assert.assertSame(this.authScheme, this.authState.getAuthScheme()); Assert.assertSame(this.credentials, this.authState.getCredentials()); Assert.assertNull(this.authState.getAuthOptions()); Assert.assertTrue(request.containsHeader(AUTH.WWW_AUTH_RESP)); Mockito.verify(this.authScheme).authenticate(this.credentials, request, this.context); } @Test public void testAuthChallengeStateMultipleOption() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); this.authState.setState(AuthProtocolState.CHALLENGED); final LinkedList authOptions = new LinkedList(); final ContextAwareAuthScheme authScheme1 = Mockito.mock(ContextAwareAuthScheme.class); Mockito.doThrow(new AuthenticationException()).when(authScheme1).authenticate( Mockito.any(Credentials.class), Mockito.any(HttpRequest.class), Mockito.any(HttpContext.class)); final ContextAwareAuthScheme authScheme2 = Mockito.mock(ContextAwareAuthScheme.class); Mockito.when(authScheme2.authenticate( Mockito.any(Credentials.class), Mockito.any(HttpRequest.class), Mockito.any(HttpContext.class))).thenReturn(new BasicHeader(AUTH.WWW_AUTH_RESP, "stuff")); authOptions.add(new AuthOption(authScheme1, this.credentials)); authOptions.add(new AuthOption(authScheme2, this.credentials)); this.authState.update(authOptions); this.httpAuthenticator.generateAuthResponse(request, authState, context); Assert.assertSame(authScheme2, this.authState.getAuthScheme()); Assert.assertSame(this.credentials, this.authState.getCredentials()); Assert.assertNull(this.authState.getAuthOptions()); Assert.assertTrue(request.containsHeader(AUTH.WWW_AUTH_RESP)); Mockito.verify(authScheme1, Mockito.times(1)).authenticate(this.credentials, request, this.context); Mockito.verify(authScheme2, Mockito.times(1)).authenticate(this.credentials, request, this.context); } @Test public void testAuthSuccess() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); this.authState.setState(AuthProtocolState.SUCCESS); this.authState.update(this.authScheme, this.credentials); Mockito.when(this.authScheme.isConnectionBased()).thenReturn(Boolean.FALSE); Mockito.when(this.authScheme.authenticate( Mockito.any(Credentials.class), Mockito.any(HttpRequest.class), Mockito.any(HttpContext.class))).thenReturn(new BasicHeader(AUTH.WWW_AUTH_RESP, "stuff")); this.httpAuthenticator.generateAuthResponse(request, authState, context); Assert.assertSame(this.authScheme, this.authState.getAuthScheme()); Assert.assertSame(this.credentials, this.authState.getCredentials()); Assert.assertNull(this.authState.getAuthOptions()); Assert.assertTrue(request.containsHeader(AUTH.WWW_AUTH_RESP)); Mockito.verify(this.authScheme).authenticate(this.credentials, request, this.context); } @Test public void testAuthSuccessConnectionBased() throws Exception { final HttpRequest request = new BasicHttpRequest("GET", "/"); this.authState.setState(AuthProtocolState.SUCCESS); this.authState.update(this.authScheme, this.credentials); Mockito.when(this.authScheme.isConnectionBased()).thenReturn(Boolean.TRUE); Mockito.when(this.authScheme.authenticate( Mockito.any(Credentials.class), Mockito.any(HttpRequest.class), Mockito.any(HttpContext.class))).thenReturn(new BasicHeader(AUTH.WWW_AUTH_RESP, "stuff")); this.httpAuthenticator.generateAuthResponse(request, authState, context); Assert.assertFalse(request.containsHeader(AUTH.WWW_AUTH_RESP)); Mockito.verify(this.authScheme, Mockito.never()).authenticate( Mockito.any(Credentials.class), Mockito.any(HttpRequest.class), Mockito.any(HttpContext.class)); } } ././@LongLink0100644 0000000 0000000 00000000147 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/auth/TestNTLMEngineImpl.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/auth/TestNTLMEngineImpl.ja0100644 0000000 0000000 00000023114 12301751657 032255 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import org.junit.Assert; import org.junit.Test; public class TestNTLMEngineImpl { @Test public void testMD4() throws Exception { checkMD4("", "31d6cfe0d16ae931b73c59d7e0c089c0"); checkMD4("a", "bde52cb31de33e46245e05fbdbd6fb24"); checkMD4("abc", "a448017aaf21d8525fc10ae87aa6729d"); checkMD4("message digest", "d9130a8164549fe818874806e1c7014b"); checkMD4("abcdefghijklmnopqrstuvwxyz", "d79e1c308aa5bbcdeea8ed63df412da9"); checkMD4("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "043f8582f241db351ce627e153e7f0e4"); checkMD4( "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "e33b4ddc9c38f2199c3e7b164fcc0536"); } /* Test suite helper */ static byte toNibble(final char c) { if (c >= 'a' && c <= 'f') { return (byte) (c - 'a' + 0x0a); } return (byte) (c - '0'); } /* Test suite helper */ static byte[] toBytes(final String hex) { final byte[] rval = new byte[hex.length() / 2]; int i = 0; while (i < rval.length) { rval[i] = (byte) ((toNibble(hex.charAt(i * 2)) << 4) | (toNibble(hex .charAt(i * 2 + 1)))); i++; } return rval; } /* Test suite MD4 helper */ static void checkMD4(final String input, final String hexOutput) throws Exception { NTLMEngineImpl.MD4 md4; md4 = new NTLMEngineImpl.MD4(); md4.update(input.getBytes("ASCII")); final byte[] answer = md4.getOutput(); final byte[] correctAnswer = toBytes(hexOutput); if (answer.length != correctAnswer.length) { throw new Exception("Answer length disagrees for MD4('" + input + "')"); } int i = 0; while (i < answer.length) { if (answer[i] != correctAnswer[i]) { throw new Exception("Answer value for MD4('" + input + "') disagrees at position " + Integer.toString(i)); } i++; } } @Test public void testLMResponse() throws Exception { final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen( null, null, "SecREt01", toBytes("0123456789abcdef"), null, null, null, null, null, null); checkArraysMatch(toBytes("c337cd5cbd44fc9782a667af6d427c6de67c20c2d3e77c56"), gen.getLMResponse()); } @Test public void testNTLMResponse() throws Exception { final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen( null, null, "SecREt01", toBytes("0123456789abcdef"), null, null, null, null, null, null); checkArraysMatch(toBytes("25a98c1c31e81847466b29b2df4680f39958fb8c213a9cc6"), gen.getNTLMResponse()); } @Test public void testLMv2Response() throws Exception { final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen( "DOMAIN", "user", "SecREt01", toBytes("0123456789abcdef"), "DOMAIN", null, toBytes("ffffff0011223344"), toBytes("ffffff0011223344"), null, null); checkArraysMatch(toBytes("d6e6152ea25d03b7c6ba6629c2d6aaf0ffffff0011223344"), gen.getLMv2Response()); } @Test public void testNTLMv2Response() throws Exception { final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen( "DOMAIN", "user", "SecREt01", toBytes("0123456789abcdef"), "DOMAIN", toBytes("02000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d0000000000"), toBytes("ffffff0011223344"), toBytes("ffffff0011223344"), null, toBytes("0090d336b734c301")); checkArraysMatch(toBytes("01010000000000000090d336b734c301ffffff00112233440000000002000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d000000000000000000"), gen.getNTLMv2Blob()); checkArraysMatch(toBytes("cbabbca713eb795d04c97abc01ee498301010000000000000090d336b734c301ffffff00112233440000000002000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d000000000000000000"), gen.getNTLMv2Response()); } @Test public void testLM2SessionResponse() throws Exception { final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen( "DOMAIN", "user", "SecREt01", toBytes("0123456789abcdef"), "DOMAIN", toBytes("02000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d0000000000"), toBytes("ffffff0011223344"), toBytes("ffffff0011223344"), null, toBytes("0090d336b734c301")); checkArraysMatch(toBytes("ffffff001122334400000000000000000000000000000000"), gen.getLM2SessionResponse()); } @Test public void testNTLM2SessionResponse() throws Exception { final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen( "DOMAIN", "user", "SecREt01", toBytes("0123456789abcdef"), "DOMAIN", toBytes("02000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d0000000000"), toBytes("ffffff0011223344"), toBytes("ffffff0011223344"), null, toBytes("0090d336b734c301")); checkArraysMatch(toBytes("10d550832d12b2ccb79d5ad1f4eed3df82aca4c3681dd455"), gen.getNTLM2SessionResponse()); } @Test public void testNTLMUserSessionKey() throws Exception { final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen( "DOMAIN", "user", "SecREt01", toBytes("0123456789abcdef"), "DOMAIN", toBytes("02000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d0000000000"), toBytes("ffffff0011223344"), toBytes("ffffff0011223344"), null, toBytes("0090d336b734c301")); checkArraysMatch(toBytes("3f373ea8e4af954f14faa506f8eebdc4"), gen.getNTLMUserSessionKey()); } @Test public void testType1Message() throws Exception { new NTLMEngineImpl().getType1Message("myhost", "mydomain"); } @Test public void testType3Message() throws Exception { new NTLMEngineImpl().getType3Message("me", "mypassword", "myhost", "mydomain", toBytes("0001020304050607"), 0xffffffff, null,null); new NTLMEngineImpl().getType3Message("me", "mypassword", "myhost", "mydomain", toBytes("0001020304050607"), 0xffffffff, "mytarget", toBytes("02000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d0000000000")); } @Test public void testRC4() throws Exception { checkArraysMatch(toBytes("e37f97f2544f4d7e"), NTLMEngineImpl.RC4(toBytes("0a003602317a759a"), toBytes("2785f595293f3e2813439d73a223810d"))); } /* Byte array check helper */ static void checkArraysMatch(final byte[] a1, final byte[] a2) throws Exception { Assert.assertEquals(a1.length,a2.length); for (int i = 0; i < a1.length; i++) { Assert.assertEquals(a1[i],a2[i]); } } } ././@LongLink0100644 0000000 0000000 00000000146 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/auth/TestRFC2617Scheme.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/auth/TestRFC2617Scheme.jav0100644 0000000 0000000 00000012165 12301751657 032004 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.Credentials; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.message.BasicHeader; import org.apache.http.message.BufferedHeader; import org.apache.http.util.CharArrayBuffer; import org.junit.Assert; import org.junit.Test; public class TestRFC2617Scheme { static class TestAuthScheme extends RFC2617Scheme { @Deprecated public Header authenticate( final Credentials credentials, final HttpRequest request) throws AuthenticationException { return null; } public String getSchemeName() { return "test"; } public boolean isComplete() { return false; } public boolean isConnectionBased() { return false; } } @Test public void testProcessChallenge() throws Exception { final TestAuthScheme authscheme = new TestAuthScheme(); final Header header = new BasicHeader( AUTH.WWW_AUTH, "Test realm=\"realm1\", test, test1 = stuff, test2 = \"stuff, stuff\", test3=\"crap"); authscheme.processChallenge(header); Assert.assertEquals("test", authscheme.getSchemeName()); Assert.assertEquals("TEST", authscheme.toString()); Assert.assertEquals("realm1", authscheme.getParameter("realm")); Assert.assertEquals(null, authscheme.getParameter("test")); Assert.assertEquals("stuff", authscheme.getParameter("test1")); Assert.assertEquals("stuff, stuff", authscheme.getParameter("test2")); Assert.assertEquals("\"crap", authscheme.getParameter("test3")); Assert.assertEquals(null, authscheme.getParameter(null)); } @Test public void testProcessChallengeWithLotsOfBlanks() throws Exception { final TestAuthScheme authscheme = new TestAuthScheme(); final CharArrayBuffer buffer = new CharArrayBuffer(32); buffer.append(" WWW-Authenticate: Test realm=\"realm1\""); final Header header = new BufferedHeader(buffer); authscheme.processChallenge(header); Assert.assertEquals("test", authscheme.getSchemeName()); Assert.assertEquals("realm1", authscheme.getParameter("realm")); } @Test public void testNullHeader() throws Exception { final TestAuthScheme authscheme = new TestAuthScheme(); try { authscheme.processChallenge(null); Assert.fail("IllegalArgumentException should have been thrown"); } catch (final IllegalArgumentException ex) { } } @Test(expected=MalformedChallengeException.class) public void testInvalidHeader() throws Exception { final TestAuthScheme authscheme = new TestAuthScheme(); final Header header = new BasicHeader("whatever", "Test realm=\"realm1\""); authscheme.processChallenge(header); } @Test(expected=MalformedChallengeException.class) public void testInvalidSchemeName() throws Exception { final TestAuthScheme authscheme = new TestAuthScheme(); final Header header = new BasicHeader(AUTH.WWW_AUTH, "Not-a-Test realm=\"realm1\""); authscheme.processChallenge(header); } @Test(expected=MalformedChallengeException.class) public void testEmptyHeader() throws Exception { final TestAuthScheme authscheme = new TestAuthScheme(); final Header header = new BasicHeader(AUTH.WWW_AUTH, "Test "); authscheme.processChallenge(header); } @Test(expected=MalformedChallengeException.class) public void testInvalidHeaderValue() throws Exception { final TestAuthScheme authscheme = new TestAuthScheme(); final Header header = new BasicHeader("whatever", "whatever"); authscheme.processChallenge(header); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/0040755 0000000 0000000 00000000000 12301751657 026676 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/MockClock.java0100644 0000000 0000000 00000002652 12301751657 031410 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; public class MockClock implements Clock { private long t = System.currentTimeMillis(); public long getCurrentTime() { return t; } public void setCurrentTime(final long now) { t = now; } } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/MockConnPoolControl.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/MockConnPoolControl0100644 0000000 0000000 00000006015 12301751656 032521 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.pool.ConnPoolControl; import org.apache.http.pool.PoolStats; public final class MockConnPoolControl implements ConnPoolControl { private final ConcurrentHashMap maxPerHostMap; private volatile int totalMax; private volatile int defaultMax; public MockConnPoolControl() { super(); this.maxPerHostMap = new ConcurrentHashMap(); this.totalMax = 20; this.defaultMax = 2; } public void setMaxTotal(final int max) { this.totalMax = max; } public int getMaxTotal() { return this.totalMax; } public PoolStats getTotalStats() { return new PoolStats(-1, -1, -1, this.totalMax); } public PoolStats getStats(final HttpRoute route) { return new PoolStats(-1, -1, -1, getMaxPerRoute(route)); } public int getDefaultMaxPerRoute() { return this.defaultMax; } public void setDefaultMaxPerRoute(final int max) { this.defaultMax = max; } public void setMaxPerRoute(final HttpRoute route, final int max) { this.maxPerHostMap.put(route, Integer.valueOf(max)); } public int getMaxPerRoute(final HttpRoute route) { final Integer max = this.maxPerHostMap.get(route); if (max != null) { return max.intValue(); } else { return this.defaultMax; } } public void setMaxForRoutes(final Map map) { if (map == null) { return; } this.maxPerHostMap.clear(); this.maxPerHostMap.putAll(map); } @Override public String toString() { return this.maxPerHostMap.toString(); } } ././@LongLink0100644 0000000 0000000 00000000155 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestAIMDBackoffManager.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestAIMDBackoffMana0100644 0000000 0000000 00000013721 12301751657 032245 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.Random; import org.apache.http.HttpHost; import org.apache.http.client.BackoffManager; import org.apache.http.conn.routing.HttpRoute; import org.junit.Before; import org.junit.Test; public class TestAIMDBackoffManager { private AIMDBackoffManager impl; private MockConnPoolControl connPerRoute; private HttpRoute route; private MockClock clock; @Before public void setUp() { connPerRoute = new MockConnPoolControl(); route = new HttpRoute(new HttpHost("localhost:80")); clock = new MockClock(); impl = new AIMDBackoffManager(connPerRoute, clock); impl.setPerHostConnectionCap(10); } @Test public void isABackoffManager() { assertTrue(impl instanceof BackoffManager); } @Test public void halvesConnectionsOnBackoff() { connPerRoute.setMaxPerRoute(route, 4); impl.backOff(route); assertEquals(2, connPerRoute.getMaxPerRoute(route)); } @Test public void doesNotBackoffBelowOneConnection() { connPerRoute.setMaxPerRoute(route, 1); impl.backOff(route); assertEquals(1, connPerRoute.getMaxPerRoute(route)); } @Test public void increasesByOneOnProbe() { connPerRoute.setMaxPerRoute(route, 2); impl.probe(route); assertEquals(3, connPerRoute.getMaxPerRoute(route)); } @Test public void doesNotIncreaseBeyondPerHostMaxOnProbe() { connPerRoute.setDefaultMaxPerRoute(5); connPerRoute.setMaxPerRoute(route, 5); impl.setPerHostConnectionCap(5); impl.probe(route); assertEquals(5, connPerRoute.getMaxPerRoute(route)); } @Test public void backoffDoesNotAdjustDuringCoolDownPeriod() { connPerRoute.setMaxPerRoute(route, 4); final long now = System.currentTimeMillis(); clock.setCurrentTime(now); impl.backOff(route); final long max = connPerRoute.getMaxPerRoute(route); clock.setCurrentTime(now + 1); impl.backOff(route); assertEquals(max, connPerRoute.getMaxPerRoute(route)); } @Test public void backoffStillAdjustsAfterCoolDownPeriod() { connPerRoute.setMaxPerRoute(route, 8); final long now = System.currentTimeMillis(); clock.setCurrentTime(now); impl.backOff(route); final long max = connPerRoute.getMaxPerRoute(route); clock.setCurrentTime(now + 10 * 1000L); impl.backOff(route); assertTrue(max == 1 || max > connPerRoute.getMaxPerRoute(route)); } @Test public void probeDoesNotAdjustDuringCooldownPeriod() { connPerRoute.setMaxPerRoute(route, 4); final long now = System.currentTimeMillis(); clock.setCurrentTime(now); impl.probe(route); final long max = connPerRoute.getMaxPerRoute(route); clock.setCurrentTime(now + 1); impl.probe(route); assertEquals(max, connPerRoute.getMaxPerRoute(route)); } @Test public void probeStillAdjustsAfterCoolDownPeriod() { connPerRoute.setMaxPerRoute(route, 8); final long now = System.currentTimeMillis(); clock.setCurrentTime(now); impl.probe(route); final long max = connPerRoute.getMaxPerRoute(route); clock.setCurrentTime(now + 10 * 1000L); impl.probe(route); assertTrue(max < connPerRoute.getMaxPerRoute(route)); } @Test public void willBackoffImmediatelyEvenAfterAProbe() { connPerRoute.setMaxPerRoute(route, 8); final long now = System.currentTimeMillis(); clock.setCurrentTime(now); impl.probe(route); final long max = connPerRoute.getMaxPerRoute(route); clock.setCurrentTime(now + 1); impl.backOff(route); assertTrue(connPerRoute.getMaxPerRoute(route) < max); } @Test public void backOffFactorIsConfigurable() { connPerRoute.setMaxPerRoute(route, 10); impl.setBackoffFactor(0.9); impl.backOff(route); assertEquals(9, connPerRoute.getMaxPerRoute(route)); } @Test public void coolDownPeriodIsConfigurable() { long cd = new Random().nextLong() / 2; if (cd < 0) { cd *= -1; } if (cd < 1) { cd++; } final long now = System.currentTimeMillis(); impl.setCooldownMillis(cd); clock.setCurrentTime(now); impl.probe(route); final int max0 = connPerRoute.getMaxPerRoute(route); clock.setCurrentTime(now); impl.probe(route); assertEquals(max0, connPerRoute.getMaxPerRoute(route)); clock.setCurrentTime(now + cd + 1); impl.probe(route); assertTrue(max0 < connPerRoute.getMaxPerRoute(route)); } } ././@LongLink0100644 0000000 0000000 00000000161 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestAuthenticationStrategy.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestAuthenticationS0100644 0000000 0000000 00000051565 12301751656 032573 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Queue; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthOption; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthCache; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.AuthSchemes; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.auth.BasicSchemeFactory; import org.apache.http.impl.auth.DigestScheme; import org.apache.http.impl.auth.DigestSchemeFactory; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpResponse; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; /** * Simple tests for {@link AuthenticationStrategyImpl}. */ public class TestAuthenticationStrategy { @Test(expected=IllegalArgumentException.class) public void testIsAuthenticationRequestedInvalidInput() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpHost host = new HttpHost("localhost", 80); final HttpClientContext context = HttpClientContext.create(); authStrategy.isAuthenticationRequested(host, null, context); } @Test public void testTargetAuthRequested() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); final HttpHost host = new HttpHost("localhost", 80); final HttpClientContext context = HttpClientContext.create(); Assert.assertTrue(authStrategy.isAuthenticationRequested(host, response, context)); } @Test public void testProxyAuthRequested() throws Exception { final ProxyAuthenticationStrategy authStrategy = new ProxyAuthenticationStrategy(); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED, "UNAUTHORIZED"); final HttpHost host = new HttpHost("localhost", 80); final HttpClientContext context = HttpClientContext.create(); Assert.assertTrue(authStrategy.isAuthenticationRequested(host, response, context)); } @Test(expected=IllegalArgumentException.class) public void testGetChallengesInvalidInput() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpHost host = new HttpHost("localhost", 80); final HttpClientContext context = HttpClientContext.create(); authStrategy.getChallenges(host, null, context); } @Test public void testGetChallenges() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpClientContext context = HttpClientContext.create(); final HttpHost host = new HttpHost("localhost", 80); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); final Header h1 = new BasicHeader(AUTH.WWW_AUTH, " Basic realm=\"test\""); final Header h2 = new BasicHeader(AUTH.WWW_AUTH, "\t\tDigest realm=\"realm1\", nonce=\"1234\""); final Header h3 = new BasicHeader(AUTH.WWW_AUTH, "WhatEver realm=\"realm1\", stuff=\"1234\""); response.addHeader(h1); response.addHeader(h2); response.addHeader(h3); final Map challenges = authStrategy.getChallenges(host, response, context); Assert.assertNotNull(challenges); Assert.assertEquals(3, challenges.size()); Assert.assertSame(h1, challenges.get("basic")); Assert.assertSame(h2, challenges.get("digest")); Assert.assertSame(h3, challenges.get("whatever")); } @Test public void testSelectInvalidInput() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final Map challenges = new HashMap(); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); final HttpHost authhost = new HttpHost("locahost", 80); final HttpClientContext context = HttpClientContext.create(); try { authStrategy.select(null, authhost, response, context); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException ex) { } try { authStrategy.select(challenges, null, response, context); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException ex) { } try { authStrategy.select(challenges, authhost, null, context); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException ex) { } try { authStrategy.select(challenges, authhost, response, null); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException ex) { } } @Test public void testSelectNoSchemeRegistry() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); final HttpHost authhost = new HttpHost("locahost", 80); final HttpClientContext context = HttpClientContext.create(); final Map challenges = new HashMap(); challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"test\"")); challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\"")); final Queue options = authStrategy.select(challenges, authhost, response, context); Assert.assertNotNull(options); Assert.assertEquals(0, options.size()); } @Test public void testSelectNoCredentialsProvider() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); final HttpHost authhost = new HttpHost("locahost", 80); final HttpClientContext context = HttpClientContext.create(); final Map challenges = new HashMap(); challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"test\"")); challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\"")); final Registry authSchemeRegistry = RegistryBuilder.create() .register("basic", new BasicSchemeFactory()) .register("digest", new DigestSchemeFactory()).build(); context.setAuthSchemeRegistry(authSchemeRegistry); final Queue options = authStrategy.select(challenges, authhost, response, context); Assert.assertNotNull(options); Assert.assertEquals(0, options.size()); } @Test public void testNoCredentials() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); final HttpHost authhost = new HttpHost("locahost", 80); final HttpClientContext context = HttpClientContext.create(); final Map challenges = new HashMap(); challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"realm1\"")); challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm2\", nonce=\"1234\"")); final Registry authSchemeRegistry = RegistryBuilder.create() .register("basic", new BasicSchemeFactory()) .register("digest", new DigestSchemeFactory()).build(); context.setAuthSchemeRegistry(authSchemeRegistry); final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); context.setCredentialsProvider(credentialsProvider); final Queue options = authStrategy.select(challenges, authhost, response, context); Assert.assertNotNull(options); Assert.assertEquals(0, options.size()); } @Test public void testCredentialsFound() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); final HttpHost authhost = new HttpHost("somehost", 80); final HttpClientContext context = HttpClientContext.create(); final Map challenges = new HashMap(); challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"realm1\"")); challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm2\", nonce=\"1234\"")); final Registry authSchemeRegistry = RegistryBuilder.create() .register("basic", new BasicSchemeFactory()) .register("digest", new DigestSchemeFactory()).build(); context.setAuthSchemeRegistry(authSchemeRegistry); final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(new AuthScope("somehost", 80, "realm2"), new UsernamePasswordCredentials("user", "pwd")); context.setCredentialsProvider(credentialsProvider); final Queue options = authStrategy.select(challenges, authhost, response, context); Assert.assertNotNull(options); Assert.assertEquals(1, options.size()); final AuthOption option = options.remove(); Assert.assertTrue(option.getAuthScheme() instanceof DigestScheme); } @Test public void testUnsupportedScheme() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); final HttpHost authhost = new HttpHost("somehost", 80); final HttpClientContext context = HttpClientContext.create(); final Map challenges = new HashMap(); challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"realm1\"")); challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm2\", nonce=\"1234\"")); challenges.put("whatever", new BasicHeader(AUTH.WWW_AUTH, "Whatever realm=\"realm3\"")); final Registry authSchemeRegistry = RegistryBuilder.create() .register("basic", new BasicSchemeFactory()) .register("digest", new DigestSchemeFactory()).build(); context.setAuthSchemeRegistry(authSchemeRegistry); final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(new AuthScope("somehost", 80), new UsernamePasswordCredentials("user", "pwd")); context.setCredentialsProvider(credentialsProvider); final Queue options = authStrategy.select(challenges, authhost, response, context); Assert.assertNotNull(options); Assert.assertEquals(2, options.size()); final AuthOption option1 = options.remove(); Assert.assertTrue(option1.getAuthScheme() instanceof DigestScheme); final AuthOption option2 = options.remove(); Assert.assertTrue(option2.getAuthScheme() instanceof BasicScheme); } @Test public void testCustomAuthPreference() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED"); final RequestConfig config = RequestConfig.custom() .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)) .build(); final HttpHost authhost = new HttpHost("somehost", 80); final HttpClientContext context = HttpClientContext.create(); final Map challenges = new HashMap(); challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"realm1\"")); challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm2\", nonce=\"1234\"")); final Registry authSchemeRegistry = RegistryBuilder.create() .register("basic", new BasicSchemeFactory()) .register("digest", new DigestSchemeFactory()).build(); context.setAuthSchemeRegistry(authSchemeRegistry); context.setRequestConfig(config); final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(new AuthScope("somehost", 80), new UsernamePasswordCredentials("user", "pwd")); context.setCredentialsProvider(credentialsProvider); final Queue options = authStrategy.select(challenges, authhost, response, context); Assert.assertNotNull(options); Assert.assertEquals(1, options.size()); final AuthOption option1 = options.remove(); Assert.assertTrue(option1.getAuthScheme() instanceof BasicScheme); } @Test public void testAuthSucceededInvalidInput() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpHost authhost = new HttpHost("locahost", 80); final BasicScheme authScheme = new BasicScheme(); final HttpClientContext context = HttpClientContext.create(); try { authStrategy.authSucceeded(null, authScheme, context); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException ex) { } try { authStrategy.authSucceeded(authhost, null, context); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException ex) { } try { authStrategy.authSucceeded(authhost, authScheme, null); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException ex) { } } @Test public void testAuthSucceeded() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpHost authhost = new HttpHost("somehost", 80); final BasicScheme authScheme = new BasicScheme(); authScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test")); final AuthCache authCache = Mockito.mock(AuthCache.class); final HttpClientContext context = HttpClientContext.create(); context.setAuthCache(authCache); authStrategy.authSucceeded(authhost, authScheme, context); Mockito.verify(authCache).put(authhost, authScheme); } @Test public void testAuthSucceededNoCache() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpHost authhost = new HttpHost("somehost", 80); final BasicScheme authScheme = new BasicScheme(); authScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test")); final HttpClientContext context = HttpClientContext.create(); context.setAuthCache(null); authStrategy.authSucceeded(authhost, authScheme, context); final AuthCache authCache = context.getAuthCache(); Assert.assertNotNull(authCache); } @Test public void testAuthScemeNotCompleted() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpHost authhost = new HttpHost("somehost", 80); final BasicScheme authScheme = new BasicScheme(); final AuthCache authCache = Mockito.mock(AuthCache.class); final HttpClientContext context = HttpClientContext.create(); context.setAuthCache(authCache); authStrategy.authSucceeded(authhost, authScheme, context); Mockito.verify(authCache, Mockito.never()).put(authhost, authScheme); } @Test public void testAuthScemeNonCacheable() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpHost authhost = new HttpHost("somehost", 80); final AuthScheme authScheme = Mockito.mock(AuthScheme.class); Mockito.when(authScheme.isComplete()).thenReturn(true); Mockito.when(authScheme.getSchemeName()).thenReturn("whatever"); final AuthCache authCache = Mockito.mock(AuthCache.class); final HttpClientContext context = HttpClientContext.create(); context.setAuthCache(authCache); authStrategy.authSucceeded(authhost, authScheme, context); Mockito.verify(authCache, Mockito.never()).put(authhost, authScheme); } @Test public void testAuthFailedInvalidInput() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpHost authhost = new HttpHost("locahost", 80); final BasicScheme authScheme = new BasicScheme(); final HttpClientContext context = HttpClientContext.create(); try { authStrategy.authFailed(null, authScheme, context); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException ex) { } try { authStrategy.authFailed(authhost, authScheme, null); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException ex) { } } @Test public void testAuthFailed() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpHost authhost = new HttpHost("somehost", 80); final BasicScheme authScheme = new BasicScheme(); authScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test")); final AuthCache authCache = Mockito.mock(AuthCache.class); final HttpClientContext context = HttpClientContext.create(); context.setAuthCache(authCache); authStrategy.authFailed(authhost, authScheme, context); Mockito.verify(authCache).remove(authhost); } @Test public void testAuthFailedNoCache() throws Exception { final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy(); final HttpHost authhost = new HttpHost("somehost", 80); final BasicScheme authScheme = new BasicScheme(); final HttpClientContext context = HttpClientContext.create(); context.setAuthCache(null); authStrategy.authFailed(authhost, authScheme, context); } } ././@LongLink0100644 0000000 0000000 00000000151 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestBasicAuthCache.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestBasicAuthCache.0100644 0000000 0000000 00000005747 12301751657 032340 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScheme; import org.apache.http.conn.SchemePortResolver; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; /** * Unit tests for {@link BasicAuthCache}. */ public class TestBasicAuthCache { @Test public void testBasics() throws Exception { final BasicAuthCache cache = new BasicAuthCache(); final AuthScheme authScheme = Mockito.mock(AuthScheme.class); cache.put(new HttpHost("localhost", 80), authScheme); Assert.assertSame(authScheme, cache.get(new HttpHost("localhost", 80))); cache.remove(new HttpHost("localhost", 80)); Assert.assertNull(cache.get(new HttpHost("localhost", 80))); cache.put(new HttpHost("localhost", 80), authScheme); cache.clear(); Assert.assertNull(cache.get(new HttpHost("localhost", 80))); } @Test public void testGetKey() throws Exception { final BasicAuthCache cache = new BasicAuthCache(); final HttpHost target = new HttpHost("localhost", 443, "https"); Assert.assertSame(target, cache.getKey(target)); Assert.assertEquals(target, cache.getKey(new HttpHost("localhost", -1, "https"))); } @Test public void testGetKeyWithSchemeRegistry() throws Exception { final SchemePortResolver schemePortResolver = Mockito.mock(SchemePortResolver.class); final BasicAuthCache cache = new BasicAuthCache(schemePortResolver); Mockito.when(schemePortResolver.resolve(new HttpHost("localhost", -1, "https"))).thenReturn(443); final HttpHost target = new HttpHost("localhost", 443, "https"); Assert.assertSame(target, cache.getKey(target)); Assert.assertEquals(target, cache.getKey(new HttpHost("localhost", -1, "https"))); } } ././@LongLink0100644 0000000 0000000 00000000153 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestBasicCookieStore.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestBasicCookieStor0100644 0000000 0000000 00000007756 12301751657 032520 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Calendar; import java.util.List; import org.apache.http.cookie.Cookie; import org.apache.http.impl.cookie.BasicClientCookie; import org.junit.Assert; import org.junit.Test; /** * Unit tests for {@link BasicCookieStore}. */ public class TestBasicCookieStore { @Test public void testBasics() throws Exception { final BasicCookieStore store = new BasicCookieStore(); store.addCookie(new BasicClientCookie("name1", "value1")); store.addCookies(new BasicClientCookie[] {new BasicClientCookie("name2", "value2")}); List l = store.getCookies(); Assert.assertNotNull(l); Assert.assertEquals(2, l.size()); Assert.assertEquals("name1", l.get(0).getName()); Assert.assertEquals("name2", l.get(1).getName()); store.clear(); l = store.getCookies(); Assert.assertNotNull(l); Assert.assertEquals(0, l.size()); } @Test public void testExpiredCookie() throws Exception { final BasicCookieStore store = new BasicCookieStore(); final BasicClientCookie cookie = new BasicClientCookie("name1", "value1"); final Calendar c = Calendar.getInstance(); c.add(Calendar.DAY_OF_YEAR, -10); cookie.setExpiryDate(c.getTime()); store.addCookie(cookie); final List l = store.getCookies(); Assert.assertNotNull(l); Assert.assertEquals(0, l.size()); } @Test public void testSerialization() throws Exception { final BasicCookieStore orig = new BasicCookieStore(); orig.addCookie(new BasicClientCookie("name1", "value1")); orig.addCookie(new BasicClientCookie("name2", "value2")); final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream(); final ObjectOutputStream outstream = new ObjectOutputStream(outbuffer); outstream.writeObject(orig); outstream.close(); final byte[] raw = outbuffer.toByteArray(); final ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw); final ObjectInputStream instream = new ObjectInputStream(inbuffer); final BasicCookieStore clone = (BasicCookieStore) instream.readObject(); final List expected = orig.getCookies(); final List clones = clone.getCookies(); Assert.assertNotNull(expected); Assert.assertNotNull(clones); Assert.assertEquals(expected.size(), clones.size()); for (int i = 0; i < expected.size(); i++) { Assert.assertEquals(expected.get(i).getName(), clones.get(i).getName()); Assert.assertEquals(expected.get(i).getValue(), clones.get(i).getValue()); } } } ././@LongLink0100644 0000000 0000000 00000000163 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestBasicCredentialsProvider.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestBasicCredential0100644 0000000 0000000 00000020517 12301751657 032477 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.junit.Assert; import org.junit.Test; /** * Simple tests for {@link BasicCredentialsProvider}. */ public class TestBasicCredentialsProvider { public final static Credentials CREDS1 = new UsernamePasswordCredentials("user1", "pass1"); public final static Credentials CREDS2 = new UsernamePasswordCredentials("user2", "pass2"); public final static AuthScope SCOPE1 = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "realm1"); public final static AuthScope SCOPE2 = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "realm2"); public final static AuthScope BOGUS = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "bogus"); public final static AuthScope DEFSCOPE = new AuthScope("host", AuthScope.ANY_PORT, "realm"); @Test public void testBasicCredentialsProviderCredentials() { final BasicCredentialsProvider state = new BasicCredentialsProvider(); state.setCredentials(SCOPE1, CREDS1); state.setCredentials(SCOPE2, CREDS2); Assert.assertEquals(CREDS1, state.getCredentials(SCOPE1)); Assert.assertEquals(CREDS2, state.getCredentials(SCOPE2)); } @Test public void testBasicCredentialsProviderNoCredentials() { final BasicCredentialsProvider state = new BasicCredentialsProvider(); Assert.assertEquals(null, state.getCredentials(BOGUS)); } @Test public void testBasicCredentialsProviderDefaultCredentials() { final BasicCredentialsProvider state = new BasicCredentialsProvider(); state.setCredentials(AuthScope.ANY, CREDS1); state.setCredentials(SCOPE2, CREDS2); Assert.assertEquals(CREDS1, state.getCredentials(BOGUS)); } @Test public void testDefaultCredentials() throws Exception { final BasicCredentialsProvider state = new BasicCredentialsProvider(); final Credentials expected = new UsernamePasswordCredentials("name", "pass"); state.setCredentials(AuthScope.ANY, expected); final Credentials got = state.getCredentials(DEFSCOPE); Assert.assertEquals(got, expected); } @Test public void testRealmCredentials() throws Exception { final BasicCredentialsProvider state = new BasicCredentialsProvider(); final Credentials expected = new UsernamePasswordCredentials("name", "pass"); state.setCredentials(DEFSCOPE, expected); final Credentials got = state.getCredentials(DEFSCOPE); Assert.assertEquals(expected, got); } @Test public void testHostCredentials() throws Exception { final BasicCredentialsProvider state = new BasicCredentialsProvider(); final Credentials expected = new UsernamePasswordCredentials("name", "pass"); state.setCredentials( new AuthScope("host", AuthScope.ANY_PORT, AuthScope.ANY_REALM), expected); final Credentials got = state.getCredentials(DEFSCOPE); Assert.assertEquals(expected, got); } @Test public void testWrongHostCredentials() throws Exception { final BasicCredentialsProvider state = new BasicCredentialsProvider(); final Credentials expected = new UsernamePasswordCredentials("name", "pass"); state.setCredentials( new AuthScope("host1", AuthScope.ANY_PORT, "realm"), expected); final Credentials got = state.getCredentials( new AuthScope("host2", AuthScope.ANY_PORT, "realm")); Assert.assertNotSame(expected, got); } @Test public void testWrongRealmCredentials() throws Exception { final BasicCredentialsProvider state = new BasicCredentialsProvider(); final Credentials cred = new UsernamePasswordCredentials("name", "pass"); state.setCredentials( new AuthScope("host", AuthScope.ANY_PORT, "realm1"), cred); final Credentials got = state.getCredentials( new AuthScope("host", AuthScope.ANY_PORT, "realm2")); Assert.assertNotSame(cred, got); } @Test public void testScopeMatching() { final AuthScope authscope1 = new AuthScope("somehost", 80, "somerealm", "somescheme"); final AuthScope authscope2 = new AuthScope("someotherhost", 80, "somerealm", "somescheme"); Assert.assertTrue(authscope1.match(authscope2) < 0); int m1 = authscope1.match( new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, "somescheme")); int m2 = authscope1.match( new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "somerealm", AuthScope.ANY_SCHEME)); Assert.assertTrue(m2 > m1); m1 = authscope1.match( new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, "somescheme")); m2 = authscope1.match( new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "somerealm", AuthScope.ANY_SCHEME)); Assert.assertTrue(m2 > m1); m1 = authscope1.match( new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "somerealm", "somescheme")); m2 = authscope1.match( new AuthScope(AuthScope.ANY_HOST, 80, AuthScope.ANY_REALM, AuthScope.ANY_SCHEME)); Assert.assertTrue(m2 > m1); m1 = authscope1.match( new AuthScope(AuthScope.ANY_HOST, 80, "somerealm", "somescheme")); m2 = authscope1.match( new AuthScope("somehost", AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthScope.ANY_SCHEME)); Assert.assertTrue(m2 > m1); m1 = authscope1.match(AuthScope.ANY); m2 = authscope1.match( new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, "somescheme")); Assert.assertTrue(m2 > m1); } @Test public void testCredentialsMatching() { final Credentials creds1 = new UsernamePasswordCredentials("name1", "pass1"); final Credentials creds2 = new UsernamePasswordCredentials("name2", "pass2"); final Credentials creds3 = new UsernamePasswordCredentials("name3", "pass3"); final AuthScope scope1 = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM); final AuthScope scope2 = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "somerealm"); final AuthScope scope3 = new AuthScope("somehost", AuthScope.ANY_PORT, AuthScope.ANY_REALM); final BasicCredentialsProvider state = new BasicCredentialsProvider(); state.setCredentials(scope1, creds1); state.setCredentials(scope2, creds2); state.setCredentials(scope3, creds3); Credentials got = state.getCredentials( new AuthScope("someotherhost", 80, "someotherrealm", "basic")); Credentials expected = creds1; Assert.assertEquals(expected, got); got = state.getCredentials( new AuthScope("someotherhost", 80, "somerealm", "basic")); expected = creds2; Assert.assertEquals(expected, got); got = state.getCredentials( new AuthScope("somehost", 80, "someotherrealm", "basic")); expected = creds3; Assert.assertEquals(expected, got); } } ././@LongLink0100644 0000000 0000000 00000000157 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestBasicResponseHandler.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestBasicResponseHa0100644 0000000 0000000 00000006511 12301751656 032471 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.InputStream; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.StatusLine; import org.apache.http.client.HttpResponseException; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicStatusLine; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; /** * Unit tests for {@link BasicResponseHandler}. */ public class TestBasicResponseHandler { @Test public void testSuccessfulResponse() throws Exception { final StatusLine sl = new BasicStatusLine(HttpVersion.HTTP_1_1, 200, "OK"); final HttpResponse response = Mockito.mock(HttpResponse.class); final HttpEntity entity = new StringEntity("stuff"); Mockito.when(response.getStatusLine()).thenReturn(sl); Mockito.when(response.getEntity()).thenReturn(entity); final BasicResponseHandler handler = new BasicResponseHandler(); final String s = handler.handleResponse(response); Assert.assertEquals("stuff", s); } @Test public void testUnsuccessfulResponse() throws Exception { final InputStream instream = Mockito.mock(InputStream.class); final HttpEntity entity = Mockito.mock(HttpEntity.class); Mockito.when(entity.isStreaming()).thenReturn(true); Mockito.when(entity.getContent()).thenReturn(instream); final StatusLine sl = new BasicStatusLine(HttpVersion.HTTP_1_1, 404, "Not Found"); final HttpResponse response = Mockito.mock(HttpResponse.class); Mockito.when(response.getStatusLine()).thenReturn(sl); Mockito.when(response.getEntity()).thenReturn(entity); final BasicResponseHandler handler = new BasicResponseHandler(); try { handler.handleResponse(response); Assert.fail("HttpResponseException expected"); } catch (final HttpResponseException ex) { Assert.assertEquals(404, ex.getStatusCode()); Assert.assertEquals("Not Found", ex.getMessage()); } Mockito.verify(entity).getContent(); Mockito.verify(instream).close(); } } ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestCloseableHttpClient.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestCloseableHttpCl0100644 0000000 0000000 00000016176 12301751657 032501 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.IOException; import java.io.InputStream; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.protocol.HttpContext; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; /** * Simple tests for {@link CloseableHttpClient}. */ public class TestCloseableHttpClient { static abstract class NoopCloseableHttpClient extends CloseableHttpClient { @Override protected CloseableHttpResponse doExecute( final HttpHost target, final HttpRequest request, final HttpContext context) throws IOException, ClientProtocolException { return null; } } private NoopCloseableHttpClient client; private InputStream content; private HttpEntity entity; private CloseableHttpResponse response; @Before public void setup() throws Exception { content = Mockito.mock(InputStream.class); entity = Mockito.mock(HttpEntity.class); response = Mockito.mock(CloseableHttpResponse.class); Mockito.when(entity.getContent()).thenReturn(content); Mockito.when(entity.isStreaming()).thenReturn(Boolean.TRUE); Mockito.when(response.getEntity()).thenReturn(entity); client = Mockito.mock(NoopCloseableHttpClient.class, Mockito.CALLS_REAL_METHODS); } @Test public void testExecuteRequestAbsoluteURI() throws Exception { final HttpGet httpget = new HttpGet("https://somehost:444/stuff"); client.execute(httpget); Mockito.verify(client).doExecute( Mockito.eq(new HttpHost("somehost", 444, "https")), Mockito.same(httpget), (HttpContext) Mockito.isNull()); } @Test public void testExecuteRequestRelativeURI() throws Exception { final HttpGet httpget = new HttpGet("/stuff"); client.execute(httpget); Mockito.verify(client).doExecute( (HttpHost) Mockito.isNull(), Mockito.same(httpget), (HttpContext) Mockito.isNull()); } @Test public void testExecuteRequestInvalidHost() throws Exception { final HttpGet httpget = new HttpGet("http://_/stuff"); client.execute(httpget); Mockito.verify(client).doExecute( Mockito.eq(new HttpHost("_", -1, "http")), Mockito.same(httpget), (HttpContext) Mockito.isNull()); } @Test(expected=ClientProtocolException.class) public void testExecuteRequestInvalidHost2() throws Exception { final HttpGet httpget = new HttpGet("http://@/stuff"); client.execute(httpget); } @Test public void testExecuteRequest() throws Exception { final HttpGet httpget = new HttpGet("https://somehost:444/stuff"); Mockito.when(client.doExecute( new HttpHost("somehost", 444, "https"), httpget, null)).thenReturn(response); final CloseableHttpResponse result = client.execute(httpget); Assert.assertSame(response, result); } @Test @SuppressWarnings("unchecked") public void testExecuteRequestHandleResponse() throws Exception { final HttpGet httpget = new HttpGet("https://somehost:444/stuff"); Mockito.when(client.doExecute( new HttpHost("somehost", 444, "https"), httpget, null)).thenReturn(response); final ResponseHandler handler = Mockito.mock(ResponseHandler.class); client.execute(httpget, handler); Mockito.verify(client).doExecute( Mockito.eq(new HttpHost("somehost", 444, "https")), Mockito.same(httpget), (HttpContext) Mockito.isNull()); Mockito.verify(handler).handleResponse(response); Mockito.verify(content).close(); } @Test(expected=IOException.class) @SuppressWarnings("unchecked") public void testExecuteRequestHandleResponseIOException() throws Exception { final HttpGet httpget = new HttpGet("https://somehost:444/stuff"); Mockito.when(client.doExecute( new HttpHost("somehost", 444, "https"), httpget, null)).thenReturn(response); final ResponseHandler handler = Mockito.mock(ResponseHandler.class); Mockito.when(handler.handleResponse(response)).thenThrow(new IOException()); try { client.execute(httpget, handler); } catch (final IOException ex) { Mockito.verify(client).doExecute( Mockito.eq(new HttpHost("somehost", 444, "https")), Mockito.same(httpget), (HttpContext) Mockito.isNull()); Mockito.verify(content).close(); throw ex; } } @Test(expected=RuntimeException.class) @SuppressWarnings("unchecked") public void testExecuteRequestHandleResponseHttpException() throws Exception { final HttpGet httpget = new HttpGet("https://somehost:444/stuff"); Mockito.when(client.doExecute( new HttpHost("somehost", 444, "https"), httpget, null)).thenReturn(response); final ResponseHandler handler = Mockito.mock(ResponseHandler.class); Mockito.when(handler.handleResponse(response)).thenThrow(new RuntimeException()); try { client.execute(httpget, handler); } catch (final RuntimeException ex) { Mockito.verify(client).doExecute( Mockito.eq(new HttpHost("somehost", 444, "https")), Mockito.same(httpget), (HttpContext) Mockito.isNull()); Mockito.verify(content).close(); throw ex; } } } ././@LongLink0100644 0000000 0000000 00000000163 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestCookieIdentityComparator.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestCookieIdentityC0100644 0000000 0000000 00000013703 12301751657 032510 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.cookie.CookieIdentityComparator; import org.apache.http.impl.cookie.BasicClientCookie; import org.junit.Assert; import org.junit.Test; /** * Simple tests for {@link CookieIdentityComparator}. */ public class TestCookieIdentityComparator { @Test public void testCookieIdentityComparasionByName() { final CookieIdentityComparator comparator = new CookieIdentityComparator(); final BasicClientCookie c1 = new BasicClientCookie("name", "value1"); final BasicClientCookie c2 = new BasicClientCookie("name", "value2"); Assert.assertTrue(comparator.compare(c1, c2) == 0); final BasicClientCookie c3 = new BasicClientCookie("name1", "value"); final BasicClientCookie c4 = new BasicClientCookie("name2", "value"); Assert.assertFalse(comparator.compare(c3, c4) == 0); } @Test public void testCookieIdentityComparasionByNameAndDomain() { final CookieIdentityComparator comparator = new CookieIdentityComparator(); final BasicClientCookie c1 = new BasicClientCookie("name", "value1"); c1.setDomain("www.domain.com"); final BasicClientCookie c2 = new BasicClientCookie("name", "value2"); c2.setDomain("www.domain.com"); Assert.assertTrue(comparator.compare(c1, c2) == 0); final BasicClientCookie c3 = new BasicClientCookie("name", "value1"); c3.setDomain("www.domain.com"); final BasicClientCookie c4 = new BasicClientCookie("name", "value2"); c4.setDomain("domain.com"); Assert.assertFalse(comparator.compare(c3, c4) == 0); } @Test public void testCookieIdentityComparasionByNameAndNullDomain() { final CookieIdentityComparator comparator = new CookieIdentityComparator(); final BasicClientCookie c1 = new BasicClientCookie("name", "value1"); c1.setDomain(null); final BasicClientCookie c2 = new BasicClientCookie("name", "value2"); c2.setDomain(null); Assert.assertTrue(comparator.compare(c1, c2) == 0); final BasicClientCookie c3 = new BasicClientCookie("name", "value1"); c3.setDomain("www.domain.com"); final BasicClientCookie c4 = new BasicClientCookie("name", "value2"); c4.setDomain(null); Assert.assertFalse(comparator.compare(c3, c4) == 0); } @Test public void testCookieIdentityComparasionByNameAndLocalHost() { final CookieIdentityComparator comparator = new CookieIdentityComparator(); final BasicClientCookie c1 = new BasicClientCookie("name", "value1"); c1.setDomain("localhost"); final BasicClientCookie c2 = new BasicClientCookie("name", "value2"); c2.setDomain("localhost"); Assert.assertTrue(comparator.compare(c1, c2) == 0); final BasicClientCookie c3 = new BasicClientCookie("name", "value1"); c3.setDomain("localhost.local"); final BasicClientCookie c4 = new BasicClientCookie("name", "value2"); c4.setDomain("localhost"); Assert.assertTrue(comparator.compare(c3, c4) == 0); } @Test public void testCookieIdentityComparasionByNameDomainAndPath() { final CookieIdentityComparator comparator = new CookieIdentityComparator(); final BasicClientCookie c1 = new BasicClientCookie("name", "value1"); c1.setDomain("www.domain.com"); c1.setPath("/whatever"); final BasicClientCookie c2 = new BasicClientCookie("name", "value2"); c2.setDomain("www.domain.com"); c2.setPath("/whatever"); Assert.assertTrue(comparator.compare(c1, c2) == 0); final BasicClientCookie c3 = new BasicClientCookie("name", "value1"); c3.setDomain("www.domain.com"); c3.setPath("/whatever"); final BasicClientCookie c4 = new BasicClientCookie("name", "value2"); c4.setDomain("domain.com"); c4.setPath("/whatever-not"); Assert.assertFalse(comparator.compare(c3, c4) == 0); } @Test public void testCookieIdentityComparasionByNameDomainAndNullPath() { final CookieIdentityComparator comparator = new CookieIdentityComparator(); final BasicClientCookie c1 = new BasicClientCookie("name", "value1"); c1.setDomain("www.domain.com"); c1.setPath("/"); final BasicClientCookie c2 = new BasicClientCookie("name", "value2"); c2.setDomain("www.domain.com"); c2.setPath(null); Assert.assertTrue(comparator.compare(c1, c2) == 0); final BasicClientCookie c3 = new BasicClientCookie("name", "value1"); c3.setDomain("www.domain.com"); c3.setPath("/whatever"); final BasicClientCookie c4 = new BasicClientCookie("name", "value2"); c4.setDomain("domain.com"); c4.setPath(null); Assert.assertFalse(comparator.compare(c3, c4) == 0); } } ././@LongLink0100644 0000000 0000000 00000000161 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultBackoffStrategy.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultBackoffS0100644 0000000 0000000 00000006007 12301751657 032444 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.net.ConnectException; import java.net.SocketTimeoutException; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.client.ConnectionBackoffStrategy; import org.apache.http.conn.ConnectionPoolTimeoutException; import org.apache.http.message.BasicHttpResponse; import org.junit.Before; import org.junit.Test; public class TestDefaultBackoffStrategy { private DefaultBackoffStrategy impl; @Before public void setUp() { impl = new DefaultBackoffStrategy(); } @Test public void isABackoffStrategy() { assertTrue(impl instanceof ConnectionBackoffStrategy); } @Test public void backsOffForSocketTimeouts() { assertTrue(impl.shouldBackoff(new SocketTimeoutException())); } @Test public void backsOffForConnectionTimeouts() { assertTrue(impl.shouldBackoff(new ConnectException())); } @Test public void doesNotBackOffForConnectionManagerTimeout() { assertFalse(impl.shouldBackoff(new ConnectionPoolTimeoutException())); } @Test public void backsOffForServiceUnavailable() { final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_SERVICE_UNAVAILABLE, "Service Unavailable"); assertTrue(impl.shouldBackoff(resp)); } @Test public void doesNotBackOffForNon503StatusCodes() { for(int i = 100; i <= 599; i++) { if (i == HttpStatus.SC_SERVICE_UNAVAILABLE) { continue; } final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, i, "Foo"); assertFalse(impl.shouldBackoff(resp)); } } } ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultConnKeepAliveStrategy.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultConnKeep0100644 0000000 0000000 00000010322 12301751657 032463 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.conn.ConnectionKeepAliveStrategy; import org.apache.http.message.BasicHttpResponse; import org.apache.http.message.BasicStatusLine; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.junit.Assert; import org.junit.Test; /** * Simple tests for {@link DefaultConnectionKeepAliveStrategy}. */ public class TestDefaultConnKeepAliveStrategy { @Test(expected=IllegalArgumentException.class) public void testIllegalResponseArg() throws Exception { final HttpContext context = new BasicHttpContext(null); final ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy(); keepAliveStrat.getKeepAliveDuration(null, context); } @Test public void testNoKeepAliveHeader() throws Exception { final HttpContext context = new BasicHttpContext(null); final HttpResponse response = new BasicHttpResponse( new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK")); final ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy(); final long d = keepAliveStrat.getKeepAliveDuration(response, context); Assert.assertEquals(-1, d); } @Test public void testEmptyKeepAliveHeader() throws Exception { final HttpContext context = new BasicHttpContext(null); final HttpResponse response = new BasicHttpResponse( new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK")); response.addHeader("Keep-Alive", "timeout, max=20"); final ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy(); final long d = keepAliveStrat.getKeepAliveDuration(response, context); Assert.assertEquals(-1, d); } @Test public void testInvalidKeepAliveHeader() throws Exception { final HttpContext context = new BasicHttpContext(null); final HttpResponse response = new BasicHttpResponse( new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK")); response.addHeader("Keep-Alive", "timeout=whatever, max=20"); final ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy(); final long d = keepAliveStrat.getKeepAliveDuration(response, context); Assert.assertEquals(-1, d); } @Test public void testKeepAliveHeader() throws Exception { final HttpContext context = new BasicHttpContext(null); final HttpResponse response = new BasicHttpResponse( new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK")); response.addHeader("Keep-Alive", "timeout=300, max=20"); final ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy(); final long d = keepAliveStrat.getKeepAliveDuration(response, context); Assert.assertEquals(300000, d); } } ././@LongLink0100644 0000000 0000000 00000000171 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultHttpRequestRetryHandler.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultHttpRequ0100644 0000000 0000000 00000010621 12301751657 032537 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.io.IOException; import java.net.UnknownHostException; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpCoreContext; import org.junit.Assert; import org.junit.Test; @SuppressWarnings("boxing") // test class public class TestDefaultHttpRequestRetryHandler { @Test public void noRetryOnConnectTimeout() throws Exception { final HttpContext context = mock(HttpContext.class); final HttpUriRequest request = mock(HttpUriRequest.class); final DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(); Assert.assertEquals(3, retryHandler.getRetryCount()); when(request.isAborted()).thenReturn(Boolean.FALSE); when(context.getAttribute(HttpCoreContext.HTTP_REQUEST)).thenReturn(request); Assert.assertFalse(retryHandler.retryRequest(new ConnectTimeoutException(), 1, context)); } @Test public void noRetryOnUnknownHost() throws Exception { final HttpContext context = mock(HttpContext.class); final HttpUriRequest request = mock(HttpUriRequest.class); final DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(); when(request.isAborted()).thenReturn(Boolean.FALSE); when(context.getAttribute(HttpCoreContext.HTTP_REQUEST)).thenReturn(request); Assert.assertFalse(retryHandler.retryRequest(new UnknownHostException(), 1, context)); } @Test public void noRetryOnAbortedRequests() throws Exception{ final HttpContext context = mock(HttpContext.class); final HttpUriRequest request = mock(HttpUriRequest.class); final DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(); when(request.isAborted()).thenReturn(Boolean.TRUE); when(context.getAttribute(HttpCoreContext.HTTP_REQUEST)).thenReturn(request); Assert.assertFalse(retryHandler.retryRequest(new IOException(),3,context)); } @Test public void retryOnNonAbortedRequests() throws Exception{ final HttpContext context = mock(HttpContext.class); final HttpUriRequest request = mock(HttpUriRequest.class); final DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(); when(request.isAborted()).thenReturn(Boolean.FALSE); when(context.getAttribute(HttpCoreContext.HTTP_REQUEST)).thenReturn(request); Assert.assertTrue(retryHandler.retryRequest(new IOException(),3,context)); } @Test public void noRetryOnConnectionTimeout() throws Exception{ final HttpContext context = mock(HttpContext.class); final HttpUriRequest request = mock(HttpUriRequest.class); final DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(); when(request.isAborted()).thenReturn(false); when(context.getAttribute(HttpCoreContext.HTTP_REQUEST)).thenReturn(request); Assert.assertFalse(retryHandler.retryRequest(new ConnectTimeoutException(),3,context)); } } ././@LongLink0100644 0000000 0000000 00000000162 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultRedirectStrategy.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultRedirect0100644 0000000 0000000 00000052312 12301751657 032527 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.net.URI; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.ProtocolException; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpTrace; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.entity.BasicHttpEntity; import org.apache.http.message.BasicHttpResponse; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpCoreContext; import org.junit.Assert; import org.junit.Test; public class TestDefaultRedirectStrategy { @Test public void testIsRedirectable() { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); Assert.assertTrue(redirectStrategy.isRedirectable(HttpGet.METHOD_NAME)); Assert.assertTrue(redirectStrategy.isRedirectable(HttpHead.METHOD_NAME)); Assert.assertFalse(redirectStrategy.isRedirectable(HttpPut.METHOD_NAME)); Assert.assertFalse(redirectStrategy.isRedirectable(HttpPost.METHOD_NAME)); Assert.assertFalse(redirectStrategy.isRedirectable(HttpDelete.METHOD_NAME)); } @Test public void testIsRedirectedMovedTemporary() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); response.addHeader("Location", "http://localhost/stuff"); Assert.assertTrue(redirectStrategy.isRedirected(httpget, response, context)); final HttpPost httppost = new HttpPost("http://localhost/"); Assert.assertFalse(redirectStrategy.isRedirected(httppost, response, context)); } @Test public void testIsRedirectedMovedTemporaryNoLocation() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); Assert.assertFalse(redirectStrategy.isRedirected(httpget, response, context)); } @Test public void testIsRedirectedMovedPermanently() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_PERMANENTLY, "Redirect"); Assert.assertTrue(redirectStrategy.isRedirected(httpget, response, context)); final HttpPost httppost = new HttpPost("http://localhost/"); Assert.assertFalse(redirectStrategy.isRedirected(httppost, response, context)); } @Test public void testIsRedirectedTemporaryRedirect() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_TEMPORARY_REDIRECT, "Redirect"); Assert.assertTrue(redirectStrategy.isRedirected(httpget, response, context)); final HttpPost httppost = new HttpPost("http://localhost/"); Assert.assertFalse(redirectStrategy.isRedirected(httppost, response, context)); } @Test public void testIsRedirectedSeeOther() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_SEE_OTHER, "Redirect"); Assert.assertTrue(redirectStrategy.isRedirected(httpget, response, context)); final HttpPost httppost = new HttpPost("http://localhost/"); Assert.assertTrue(redirectStrategy.isRedirected(httppost, response, context)); } @Test public void testIsRedirectedUnknownStatus() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 333, "Redirect"); Assert.assertFalse(redirectStrategy.isRedirected(httpget, response, context)); final HttpPost httppost = new HttpPost("http://localhost/"); Assert.assertFalse(redirectStrategy.isRedirected(httppost, response, context)); } @Test public void testIsRedirectedInvalidInput() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_SEE_OTHER, "Redirect"); try { redirectStrategy.isRedirected(null, response, context); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException expected) { } try { redirectStrategy.isRedirected(httpget, null, context); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException expected) { } } @Test public void testGetLocationUri() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); response.addHeader("Location", "http://localhost/stuff"); final URI uri = redirectStrategy.getLocationURI(httpget, response, context); Assert.assertEquals(URI.create("http://localhost/stuff"), uri); } @Test(expected=ProtocolException.class) public void testGetLocationUriMissingHeader() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); redirectStrategy.getLocationURI(httpget, response, context); } @Test(expected=ProtocolException.class) public void testGetLocationUriInvalidLocation() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); response.addHeader("Location", "http://localhost/not valid"); redirectStrategy.getLocationURI(httpget, response, context); } @Test public void testGetLocationUriRelative() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost")); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); response.addHeader("Location", "/stuff"); final URI uri = redirectStrategy.getLocationURI(httpget, response, context); Assert.assertEquals(URI.create("http://localhost/stuff"), uri); } @Test(expected=IllegalStateException.class) public void testGetLocationUriRelativeMissingTargetHost() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); response.addHeader("Location", "/stuff"); final URI uri = redirectStrategy.getLocationURI(httpget, response, context); Assert.assertEquals(URI.create("http://localhost/stuff"), uri); } @Test public void testGetLocationUriRelativeWithFragment() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost")); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); response.addHeader("Location", "/stuff#fragment"); final URI uri = redirectStrategy.getLocationURI(httpget, response, context); Assert.assertEquals(URI.create("http://localhost/stuff#fragment"), uri); } @Test public void testGetLocationUriAbsoluteWithFragment() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost")); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); response.addHeader("Location", "http://localhost/stuff#fragment"); final URI uri = redirectStrategy.getLocationURI(httpget, response, context); Assert.assertEquals(URI.create("http://localhost/stuff#fragment"), uri); } @Test public void testGetLocationUriNormalized() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost")); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); response.addHeader("Location", "http://localhost/././stuff/../morestuff"); final URI uri = redirectStrategy.getLocationURI(httpget, response, context); Assert.assertEquals(URI.create("http://localhost/morestuff"), uri); } @Test(expected=ProtocolException.class) public void testGetLocationUriRelativeLocationNotAllowed() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost")); final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(false).build(); context.setRequestConfig(config); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); response.addHeader("Location", "/stuff"); redirectStrategy.getLocationURI(httpget, response, context); } @Test public void testGetLocationUriAllowCircularRedirects() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost")); final RequestConfig config = RequestConfig.custom().setCircularRedirectsAllowed(true).build(); context.setRequestConfig(config); final URI uri1 = URI.create("http://localhost/stuff1"); final URI uri2 = URI.create("http://localhost/stuff2"); final URI uri3 = URI.create("http://localhost/stuff3"); final HttpGet httpget1 = new HttpGet("http://localhost/"); final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); response1.addHeader("Location", uri1.toASCIIString()); final HttpGet httpget2 = new HttpGet(uri1.toASCIIString()); final HttpResponse response2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); response2.addHeader("Location", uri2.toASCIIString()); final HttpGet httpget3 = new HttpGet(uri2.toASCIIString()); final HttpResponse response3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); response3.addHeader("Location", uri3.toASCIIString()); Assert.assertEquals(uri1, redirectStrategy.getLocationURI(httpget1, response1, context)); Assert.assertEquals(uri2, redirectStrategy.getLocationURI(httpget2, response2, context)); Assert.assertEquals(uri3, redirectStrategy.getLocationURI(httpget3, response3, context)); final List uris = context.getRedirectLocations(); Assert.assertNotNull(uris); Assert.assertTrue(uris.contains(uri1)); Assert.assertTrue(uris.contains(uri2)); Assert.assertTrue(uris.contains(uri3)); Assert.assertEquals(3, uris.size()); Assert.assertEquals(uri1, uris.get(0)); Assert.assertEquals(uri2, uris.get(1)); Assert.assertEquals(uri3, uris.get(2)); } @Test(expected=ProtocolException.class) public void testGetLocationUriDisallowCircularRedirects() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost")); final HttpGet httpget = new HttpGet("http://localhost/stuff"); final RequestConfig config = RequestConfig.custom().setCircularRedirectsAllowed(false).build(); context.setRequestConfig(config); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); response.addHeader("Location", "http://localhost/stuff"); final URI uri = URI.create("http://localhost/stuff"); Assert.assertEquals(uri, redirectStrategy.getLocationURI(httpget, response, context)); redirectStrategy.getLocationURI(httpget, response, context); } @Test public void testGetLocationUriInvalidInput() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("http://localhost/"); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_MOVED_TEMPORARILY, "Redirect"); response.addHeader("Location", "http://localhost/stuff"); try { redirectStrategy.getLocationURI(null, response, context); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException expected) { } try { redirectStrategy.getLocationURI(httpget, null, context); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException expected) { } try { redirectStrategy.getLocationURI(httpget, response, null); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException expected) { } } @Test public void testGetRedirectRequest() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_SEE_OTHER, "Redirect"); response.addHeader("Location", "http://localhost/stuff"); final HttpContext context1 = new BasicHttpContext(); final HttpUriRequest redirect1 = redirectStrategy.getRedirect( new HttpGet("http://localhost/"), response, context1); Assert.assertEquals("GET", redirect1.getMethod()); final HttpContext context2 = new BasicHttpContext(); final HttpUriRequest redirect2 = redirectStrategy.getRedirect( new HttpPost("http://localhost/"), response, context2); Assert.assertEquals("GET", redirect2.getMethod()); final HttpContext context3 = new BasicHttpContext(); final HttpUriRequest redirect3 = redirectStrategy.getRedirect( new HttpHead("http://localhost/"), response, context3); Assert.assertEquals("HEAD", redirect3.getMethod()); } @Test public void testGetRedirectRequestForTemporaryRedirect() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_TEMPORARY_REDIRECT, "Temporary Redirect"); response.addHeader("Location", "http://localhost/stuff"); final HttpContext context1 = new BasicHttpContext(); final HttpUriRequest redirect1 = redirectStrategy.getRedirect( new HttpTrace("http://localhost/"), response, context1); Assert.assertEquals("TRACE", redirect1.getMethod()); final HttpContext context2 = new BasicHttpContext(); final HttpPost httppost = new HttpPost("http://localhost/"); final HttpEntity entity = new BasicHttpEntity(); httppost.setEntity(entity); final HttpUriRequest redirect2 = redirectStrategy.getRedirect( httppost, response, context2); Assert.assertEquals("POST", redirect2.getMethod()); Assert.assertTrue(redirect2 instanceof HttpEntityEnclosingRequest); Assert.assertSame(entity, ((HttpEntityEnclosingRequest) redirect2).getEntity()); } @Test public void testCreateLocationURI() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); Assert.assertEquals("http://blahblah/", redirectStrategy.createLocationURI("http://BlahBlah").toASCIIString()); } @Test(expected=ProtocolException.class) public void testCreateLocationURIInvalid() throws Exception { final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); redirectStrategy.createLocationURI(":::::::"); } } ././@LongLink0100644 0000000 0000000 00000000170 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestFutureRequestExecutionService.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestFutureRequestEx0100644 0000000 0000000 00000016652 12301751657 032610 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.IOException; import java.net.InetSocketAddress; import java.util.LinkedList; import java.util.Queue; import java.util.concurrent.CancellationException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import junit.framework.Assert; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.concurrent.FutureCallback; import org.apache.http.localserver.LocalTestServer; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; import org.junit.After; import org.junit.Before; import org.junit.Test; public class TestFutureRequestExecutionService { private LocalTestServer localServer; private String uri; private FutureRequestExecutionService httpAsyncClientWithFuture; private final AtomicBoolean blocked = new AtomicBoolean(false); @Before public void before() throws Exception { this.localServer = new LocalTestServer(null, null); this.localServer.register("/wait", new HttpRequestHandler() { public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { try { while(blocked.get()) { Thread.sleep(10); } } catch (final InterruptedException e) { throw new IllegalStateException(e); } response.setStatusCode(200); } }); this.localServer.start(); final InetSocketAddress address = localServer.getServiceAddress(); uri = "http://" + address.getHostName() + ":" + address.getPort() + "/wait"; final HttpClient httpClient = HttpClientBuilder.create() .setMaxConnPerRoute(5) .build(); final ExecutorService executorService = Executors.newFixedThreadPool(5); httpAsyncClientWithFuture = new FutureRequestExecutionService(httpClient, executorService); } @After public void after() throws Exception { blocked.set(false); // any remaining requests should unblock this.localServer.stop(); httpAsyncClientWithFuture.close(); } @Test public void shouldExecuteSingleCall() throws InterruptedException, ExecutionException { final HttpRequestFutureTask task = httpAsyncClientWithFuture.execute( new HttpGet(uri), HttpClientContext.create(), new OkidokiHandler()); Assert.assertTrue("request should have returned OK", task.get().booleanValue()); } @Test(expected=CancellationException.class) public void shouldCancel() throws InterruptedException, ExecutionException { final HttpRequestFutureTask task = httpAsyncClientWithFuture.execute( new HttpGet(uri), HttpClientContext.create(), new OkidokiHandler()); task.cancel(true); task.get(); } @Test(expected=TimeoutException.class) public void shouldTimeout() throws InterruptedException, ExecutionException, TimeoutException { blocked.set(true); final HttpRequestFutureTask task = httpAsyncClientWithFuture.execute( new HttpGet(uri), HttpClientContext.create(), new OkidokiHandler()); task.get(10, TimeUnit.MILLISECONDS); } @Test public void shouldExecuteMultipleCalls() throws Exception { final int reqNo = 100; final Queue> tasks = new LinkedList>(); for(int i = 0; i < reqNo; i++) { final Future task = httpAsyncClientWithFuture.execute( new HttpGet(uri), HttpClientContext.create(), new OkidokiHandler()); tasks.add(task); } for (final Future task : tasks) { final Boolean b = task.get(); Assert.assertNotNull(b); Assert.assertTrue("request should have returned OK", b.booleanValue()); } } @Test public void shouldExecuteMultipleCallsAndCallback() throws Exception { final int reqNo = 100; final Queue> tasks = new LinkedList>(); final CountDownLatch latch = new CountDownLatch(reqNo); for(int i = 0; i < reqNo; i++) { final Future task = httpAsyncClientWithFuture.execute( new HttpGet(uri), HttpClientContext.create(), new OkidokiHandler(), new CountingCallback(latch)); tasks.add(task); } Assert.assertTrue(latch.await(5, TimeUnit.SECONDS)); for (final Future task : tasks) { final Boolean b = task.get(); Assert.assertNotNull(b); Assert.assertTrue("request should have returned OK", b.booleanValue()); } } private final class CountingCallback implements FutureCallback { private final CountDownLatch latch; CountingCallback(final CountDownLatch latch) { super(); this.latch = latch; } public void failed(final Exception ex) { latch.countDown(); } public void completed(final Boolean result) { latch.countDown(); } public void cancelled() { latch.countDown(); } } private final class OkidokiHandler implements ResponseHandler { public Boolean handleResponse( final HttpResponse response) throws ClientProtocolException, IOException { return response.getStatusLine().getStatusCode() == 200; } } } ././@LongLink0100644 0000000 0000000 00000000155 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestInternalHttpClient.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestInternalHttpCli0100644 0000000 0000000 00000020454 12301751657 032527 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.io.Closeable; import java.io.IOException; import java.util.Arrays; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CookieStore; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.Lookup; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.cookie.CookieSpecProvider; import org.apache.http.impl.execchain.ClientExecChain; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; /** * Simple tests for {@link InternalHttpClient}. */ @SuppressWarnings("deprecation") public class TestInternalHttpClient { private ClientExecChain execChain; private HttpClientConnectionManager connManager; private HttpRoutePlanner routePlanner; private Lookup cookieSpecRegistry; private Lookup authSchemeRegistry; private CookieStore cookieStore; private CredentialsProvider credentialsProvider; private RequestConfig defaultConfig; private Closeable closeable1; private Closeable closeable2; private InternalHttpClient client; @SuppressWarnings("unchecked") @Before public void setup() throws Exception { execChain = Mockito.mock(ClientExecChain.class); connManager = Mockito.mock(HttpClientConnectionManager.class); routePlanner = Mockito.mock(HttpRoutePlanner.class); cookieSpecRegistry = Mockito.mock(Lookup.class); authSchemeRegistry = Mockito.mock(Lookup.class); cookieStore = Mockito.mock(CookieStore.class); credentialsProvider = Mockito.mock(CredentialsProvider.class); defaultConfig = RequestConfig.custom().build(); closeable1 = Mockito.mock(Closeable.class); closeable2 = Mockito.mock(Closeable.class); client = new InternalHttpClient(execChain, connManager, routePlanner, cookieSpecRegistry, authSchemeRegistry, cookieStore, credentialsProvider, defaultConfig, Arrays.asList(closeable1, closeable2)); } @Test public void testExecute() throws Exception { final HttpGet httpget = new HttpGet("http://somehost/stuff"); final HttpRoute route = new HttpRoute(new HttpHost("somehost")); final ArgumentCaptor argcap = ArgumentCaptor.forClass(HttpRequestWrapper.class); Mockito.when(routePlanner.determineRoute( Mockito.eq(new HttpHost("somehost")), argcap.capture(), Mockito.any())).thenReturn(route); client.execute(httpget); Assert.assertNotNull(argcap.getValue()); Assert.assertSame(httpget, argcap.getValue().getOriginal()); Mockito.verify(execChain).execute( Mockito.same(route), Mockito.any(), Mockito.any(), Mockito.same(httpget)); } @Test(expected=ClientProtocolException.class) public void testExecuteHttpException() throws Exception { final HttpGet httpget = new HttpGet("http://somehost/stuff"); final HttpRoute route = new HttpRoute(new HttpHost("somehost")); Mockito.when(routePlanner.determineRoute( Mockito.eq(new HttpHost("somehost")), Mockito.any(), Mockito.any())).thenReturn(route); Mockito.when(execChain.execute( Mockito.same(route), Mockito.any(), Mockito.any(), Mockito.same(httpget))).thenThrow(new HttpException()); client.execute(httpget); } @Test public void testExecuteDefaultContext() throws Exception { final HttpGet httpget = new HttpGet("http://somehost/stuff"); final HttpClientContext context = HttpClientContext.create(); client.execute(httpget, context); Assert.assertSame(cookieSpecRegistry, context.getCookieSpecRegistry()); Assert.assertSame(authSchemeRegistry, context.getAuthSchemeRegistry()); Assert.assertSame(cookieStore, context.getCookieStore()); Assert.assertSame(credentialsProvider, context.getCredentialsProvider()); Assert.assertSame(defaultConfig, context.getRequestConfig()); } @Test public void testExecuteRequestConfig() throws Exception { final HttpGet httpget = new HttpGet("http://somehost/stuff"); final RequestConfig config = RequestConfig.custom().build(); httpget.setConfig(config); final HttpClientContext context = HttpClientContext.create(); client.execute(httpget, context); Assert.assertSame(config, context.getRequestConfig()); } @SuppressWarnings("unchecked") @Test public void testExecuteLocalContext() throws Exception { final HttpGet httpget = new HttpGet("http://somehost/stuff"); final HttpClientContext context = HttpClientContext.create(); final Lookup localCookieSpecRegistry = Mockito.mock(Lookup.class); final Lookup localAuthSchemeRegistry = Mockito.mock(Lookup.class); final CookieStore localCookieStore = Mockito.mock(CookieStore.class); final CredentialsProvider localCredentialsProvider = Mockito.mock(CredentialsProvider.class); final RequestConfig localConfig = RequestConfig.custom().build(); context.setCookieSpecRegistry(localCookieSpecRegistry); context.setAuthSchemeRegistry(localAuthSchemeRegistry); context.setCookieStore(localCookieStore); context.setCredentialsProvider(localCredentialsProvider); context.setRequestConfig(localConfig); client.execute(httpget, context); Assert.assertSame(localCookieSpecRegistry, context.getCookieSpecRegistry()); Assert.assertSame(localAuthSchemeRegistry, context.getAuthSchemeRegistry()); Assert.assertSame(localCookieStore, context.getCookieStore()); Assert.assertSame(localCredentialsProvider, context.getCredentialsProvider()); Assert.assertSame(localConfig, context.getRequestConfig()); } @Test public void testClientClose() throws Exception { client.close(); Mockito.verify(connManager).shutdown(); Mockito.verify(closeable1).close(); Mockito.verify(closeable2).close(); } @Test public void testClientCloseIOException() throws Exception { Mockito.doThrow(new IOException()).when(closeable1).close(); client.close(); Mockito.verify(connManager).shutdown(); Mockito.verify(closeable1).close(); Mockito.verify(closeable2).close(); } } ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestNullBackoffStrategy.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestNullBackoffStra0100644 0000000 0000000 00000003755 12301751657 032510 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import static org.junit.Assert.assertFalse; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.message.BasicHttpResponse; import org.junit.Before; import org.junit.Test; public class TestNullBackoffStrategy { private NullBackoffStrategy impl; @Before public void setUp() { impl = new NullBackoffStrategy(); } @Test public void doesNotBackoffForThrowables() { assertFalse(impl.shouldBackoff(new Exception())); } @Test public void doesNotBackoffForResponses() { final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_SERVICE_UNAVAILABLE, "Service Unavailable"); assertFalse(impl.shouldBackoff(resp)); } } ././@LongLink0100644 0000000 0000000 00000000153 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestRedirectLocation.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/TestRedirectLocatio0100644 0000000 0000000 00000005353 12301751656 032537 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client; import java.net.URI; import java.util.List; import org.junit.Assert; import org.junit.Test; /** * Simple tests for {@link RedirectLocations}. */ public class TestRedirectLocation { @Test public void testBasics() throws Exception { final RedirectLocations locations = new RedirectLocations(); final URI uri1 = new URI("/this"); final URI uri2 = new URI("/that"); final URI uri3 = new URI("/this-and-that"); locations.add(uri1); locations.add(uri2); locations.add(uri2); locations.add(uri3); locations.add(uri3); Assert.assertTrue(locations.contains(uri1)); Assert.assertTrue(locations.contains(uri2)); Assert.assertTrue(locations.contains(uri3)); Assert.assertFalse(locations.contains(new URI("/"))); List list = locations.getAll(); Assert.assertNotNull(list); Assert.assertEquals(5, list.size()); Assert.assertEquals(uri1, list.get(0)); Assert.assertEquals(uri2, list.get(1)); Assert.assertEquals(uri2, list.get(2)); Assert.assertEquals(uri3, list.get(3)); Assert.assertEquals(uri3, list.get(4)); Assert.assertTrue(locations.remove(uri3)); Assert.assertTrue(locations.remove(uri1)); Assert.assertFalse(locations.remove(new URI("/"))); list = locations.getAll(); Assert.assertNotNull(list); Assert.assertEquals(2, list.size()); Assert.assertEquals(uri2, list.get(0)); Assert.assertEquals(uri2, list.get(1)); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/0040755 0000000 0000000 00000000000 12301751657 031221 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000166 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/IntegrationTestBase.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/Integra0100644 0000000 0000000 00000003150 12301751656 032530 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.localserver.LocalServerTestBase; import org.junit.After; public class IntegrationTestBase extends LocalServerTestBase { protected CloseableHttpClient httpclient; @After public void shutDownClient() throws Exception { if (this.httpclient != null) { this.httpclient.close(); } } } ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestAbortHandling.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestAbo0100644 0000000 0000000 00000050543 12301751656 032510 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.IOException; import java.net.ConnectException; import java.net.InetSocketAddress; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import org.apache.http.HttpClientConnection; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.ProtocolVersion; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.concurrent.Cancellable; import org.apache.http.conn.ConnectionPoolTimeoutException; import org.apache.http.conn.ConnectionRequest; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; /** * Tests for Abort handling. */ public class TestAbortHandling extends IntegrationTestBase { @Before public void setUp() throws Exception { startServer(); } @Test public void testAbortRetry_HTTPCLIENT_1120() throws Exception { final int port = this.localServer.getServiceAddress().getPort(); final CountDownLatch wait = new CountDownLatch(1); this.localServer.register("*", new HttpRequestHandler(){ public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { try { wait.countDown(); // trigger abort Thread.sleep(2000); // allow time for abort to happen response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("Whatever"); response.setEntity(entity); } catch (final Exception e) { response.setStatusCode(HttpStatus.SC_REQUEST_TIMEOUT); } }}); final String s = "http://localhost:" + port + "/path"; final HttpGet httpget = new HttpGet(s); final Thread t = new Thread() { @Override public void run(){ try { wait.await(); } catch (final InterruptedException e) { } httpget.abort(); } }; t.start(); this.httpclient = HttpClients.createDefault(); final HttpClientContext context = HttpClientContext.create(); try { this.httpclient.execute(getServerHttp(), httpget, context); } catch (final IllegalStateException e) { } catch (final IOException e) { } final HttpRequest reqWrapper = context.getRequest(); Assert.assertNotNull("Request should exist",reqWrapper); } @Test public void testAbortInAllocate() throws Exception { final CountDownLatch connLatch = new CountDownLatch(1); final CountDownLatch awaitLatch = new CountDownLatch(1); final ConMan conMan = new ConMan(connLatch, awaitLatch); final AtomicReference throwableRef = new AtomicReference(); final CountDownLatch getLatch = new CountDownLatch(1); final CloseableHttpClient client = HttpClients.custom().setConnectionManager(conMan).build(); final HttpContext context = new BasicHttpContext(); final HttpGet httpget = new HttpGet("http://www.example.com/a"); this.httpclient = client; new Thread(new Runnable() { public void run() { try { client.execute(httpget, context); } catch(final Throwable t) { throwableRef.set(t); } finally { getLatch.countDown(); } } }).start(); Assert.assertTrue("should have tried to get a connection", connLatch.await(1, TimeUnit.SECONDS)); httpget.abort(); Assert.assertTrue("should have finished get request", getLatch.await(1, TimeUnit.SECONDS)); Assert.assertTrue("should be instanceof IOException, was: " + throwableRef.get(), throwableRef.get() instanceof IOException); Assert.assertTrue("cause should be InterruptedException, was: " + throwableRef.get().getCause(), throwableRef.get().getCause() instanceof InterruptedException); } /** * Tests that an abort called after the connection has been retrieved * but before a release trigger is set does still abort the request. */ @Test public void testAbortAfterAllocateBeforeRequest() throws Exception { this.localServer.register("*", new BasicService()); final CountDownLatch releaseLatch = new CountDownLatch(1); final PoolingHttpClientConnectionManager conMan = new PoolingHttpClientConnectionManager(); final AtomicReference throwableRef = new AtomicReference(); final CountDownLatch getLatch = new CountDownLatch(1); final CloseableHttpClient client = HttpClients.custom().setConnectionManager(conMan).build(); final HttpContext context = new BasicHttpContext(); final HttpGet httpget = new CustomGet("a", releaseLatch); this.httpclient = client; new Thread(new Runnable() { public void run() { try { client.execute(getServerHttp(), httpget, context); } catch(final Throwable t) { throwableRef.set(t); } finally { getLatch.countDown(); } } }).start(); Thread.sleep(100); // Give it a little time to proceed to release... httpget.abort(); releaseLatch.countDown(); Assert.assertTrue("should have finished get request", getLatch.await(1, TimeUnit.SECONDS)); Assert.assertTrue("should be instanceof IOException, was: " + throwableRef.get(), throwableRef.get() instanceof IOException); } /** * Tests that an abort called completely before execute * still aborts the request. */ @Test public void testAbortBeforeExecute() throws Exception { this.localServer.register("*", new BasicService()); final PoolingHttpClientConnectionManager conMan = new PoolingHttpClientConnectionManager(); final AtomicReference throwableRef = new AtomicReference(); final CountDownLatch getLatch = new CountDownLatch(1); final CountDownLatch startLatch = new CountDownLatch(1); final CloseableHttpClient client = HttpClients.custom().setConnectionManager(conMan).build(); final HttpContext context = new BasicHttpContext(); final HttpGet httpget = new HttpGet("a"); this.httpclient = client; new Thread(new Runnable() { public void run() { try { try { if(!startLatch.await(1, TimeUnit.SECONDS)) { throw new RuntimeException("Took too long to start!"); } } catch(final InterruptedException interrupted) { throw new RuntimeException("Never started!", interrupted); } client.execute(getServerHttp(), httpget, context); } catch(final Throwable t) { throwableRef.set(t); } finally { getLatch.countDown(); } } }).start(); httpget.abort(); startLatch.countDown(); Assert.assertTrue("should have finished get request", getLatch.await(1, TimeUnit.SECONDS)); Assert.assertTrue("should be instanceof IOException, was: " + throwableRef.get(), throwableRef.get() instanceof IOException); } /** * Tests that an abort called after a redirect has found a new host * still aborts in the correct place (while trying to get the new * host's route, not while doing the subsequent request). */ @Test public void testAbortAfterRedirectedRoute() throws Exception { final int port = this.localServer.getServiceAddress().getPort(); this.localServer.register("*", new BasicRedirectService(port)); final CountDownLatch connLatch = new CountDownLatch(1); final CountDownLatch awaitLatch = new CountDownLatch(1); final ConnMan4 conMan = new ConnMan4(connLatch, awaitLatch); final AtomicReference throwableRef = new AtomicReference(); final CountDownLatch getLatch = new CountDownLatch(1); final CloseableHttpClient client = HttpClients.custom().setConnectionManager(conMan).build(); final HttpContext context = new BasicHttpContext(); final HttpGet httpget = new HttpGet("a"); this.httpclient = client; new Thread(new Runnable() { public void run() { try { final HttpHost host = new HttpHost("127.0.0.1", port); client.execute(host, httpget, context); } catch(final Throwable t) { throwableRef.set(t); } finally { getLatch.countDown(); } } }).start(); Assert.assertTrue("should have tried to get a connection", connLatch.await(1, TimeUnit.SECONDS)); httpget.abort(); Assert.assertTrue("should have finished get request", getLatch.await(1, TimeUnit.SECONDS)); Assert.assertTrue("should be instanceof IOException, was: " + throwableRef.get(), throwableRef.get() instanceof IOException); Assert.assertTrue("cause should be InterruptedException, was: " + throwableRef.get().getCause(), throwableRef.get().getCause() instanceof InterruptedException); } /** * Tests that if a socket fails to connect, the allocated connection is * properly released back to the connection manager. */ @Test public void testSocketConnectFailureReleasesConnection() throws Exception { final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class); final ConnectionRequest connrequest = Mockito.mock(ConnectionRequest.class); Mockito.when(connrequest.get( Mockito.anyInt(), Mockito.any(TimeUnit.class))).thenReturn(conn); final HttpClientConnectionManager connmgr = Mockito.mock(HttpClientConnectionManager.class); Mockito.doThrow(new ConnectException()).when(connmgr).connect( Mockito.any(HttpClientConnection.class), Mockito.any(HttpRoute.class), Mockito.anyInt(), Mockito.any(HttpContext.class)); Mockito.when(connmgr.requestConnection( Mockito.any(HttpRoute.class), Mockito.any())).thenReturn(connrequest); final HttpClient client = HttpClients.custom().setConnectionManager(connmgr).build(); final HttpContext context = new BasicHttpContext(); final HttpGet httpget = new HttpGet("http://www.example.com/a"); try { client.execute(httpget, context); Assert.fail("expected IOException"); } catch(final IOException expected) {} Mockito.verify(connmgr).releaseConnection(conn, null, 0, TimeUnit.MILLISECONDS); } private static class BasicService implements HttpRequestHandler { public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { response.setStatusCode(200); response.setEntity(new StringEntity("Hello World")); } } private static class BasicRedirectService implements HttpRequestHandler { private final int statuscode = HttpStatus.SC_SEE_OTHER; private final int port; public BasicRedirectService(final int port) { this.port = port; } public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final ProtocolVersion ver = request.getRequestLine().getProtocolVersion(); response.setStatusLine(ver, this.statuscode); response.addHeader(new BasicHeader("Location", "http://localhost:" + this.port + "/newlocation/")); response.addHeader(new BasicHeader("Connection", "close")); } } private static class ConnMan4 extends PoolingHttpClientConnectionManager { private final CountDownLatch connLatch; private final CountDownLatch awaitLatch; public ConnMan4(final CountDownLatch connLatch, final CountDownLatch awaitLatch) { super(); this.connLatch = connLatch; this.awaitLatch = awaitLatch; } @Override public ConnectionRequest requestConnection(final HttpRoute route, final Object state) { // If this is the redirect route, stub the return value // so-as to pretend the host is waiting on a slot... if(route.getTargetHost().getHostName().equals("localhost")) { final Thread currentThread = Thread.currentThread(); return new ConnectionRequest() { public boolean cancel() { currentThread.interrupt(); return true; } public HttpClientConnection get( final long timeout, final TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException { connLatch.countDown(); // notify waiter that we're getting a connection // zero usually means sleep forever, but CountDownLatch doesn't interpret it that way. if(!awaitLatch.await(timeout > 0 ? timeout : Integer.MAX_VALUE, tunit)) { throw new ConnectionPoolTimeoutException(); } return Mockito.mock(HttpClientConnection.class); } }; } else { return super.requestConnection(route, state); } } } static class ConMan implements HttpClientConnectionManager { private final CountDownLatch connLatch; private final CountDownLatch awaitLatch; public ConMan(final CountDownLatch connLatch, final CountDownLatch awaitLatch) { this.connLatch = connLatch; this.awaitLatch = awaitLatch; } public void closeIdleConnections(final long idletime, final TimeUnit tunit) { throw new UnsupportedOperationException("just a mockup"); } public void closeExpiredConnections() { throw new UnsupportedOperationException("just a mockup"); } public HttpClientConnection getConnection(final HttpRoute route, final long timeout, final TimeUnit tunit) { throw new UnsupportedOperationException("just a mockup"); } public ConnectionRequest requestConnection( final HttpRoute route, final Object state) { final Thread currentThread = Thread.currentThread(); return new ConnectionRequest() { public boolean cancel() { currentThread.interrupt(); return true; } public HttpClientConnection get( final long timeout, final TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException { connLatch.countDown(); // notify waiter that we're getting a connection // zero usually means sleep forever, but CountDownLatch doesn't interpret it that way. if(!awaitLatch.await(timeout > 0 ? timeout : Integer.MAX_VALUE, tunit)) { throw new ConnectionPoolTimeoutException(); } return Mockito.mock(HttpClientConnection.class); } }; } public void shutdown() { } public void close() { } public void releaseConnection( final HttpClientConnection conn, final Object newState, final long validDuration, final TimeUnit timeUnit) { throw new UnsupportedOperationException("just a mockup"); } public void connect( final HttpClientConnection conn, final HttpRoute route, final int connectTimeout, final HttpContext context) throws IOException { throw new UnsupportedOperationException("just a mockup"); } public void upgrade( final HttpClientConnection conn, final HttpRoute route, final HttpContext context) throws IOException { throw new UnsupportedOperationException("just a mockup"); } public void routeComplete( final HttpClientConnection conn, final HttpRoute route, final HttpContext context) throws IOException { throw new UnsupportedOperationException("just a mockup"); } public void connect( final HttpClientConnection conn, final HttpHost host, final InetSocketAddress localAddress, final int connectTimeout, final HttpContext context) throws IOException { throw new UnsupportedOperationException("just a mockup"); } public void upgrade( final HttpClientConnection conn, final HttpHost host, final HttpContext context) throws IOException { throw new UnsupportedOperationException("just a mockup"); } } private static class CustomGet extends HttpGet { private final CountDownLatch releaseTriggerLatch; public CustomGet(final String uri, final CountDownLatch releaseTriggerLatch) { super(uri); this.releaseTriggerLatch = releaseTriggerLatch; } @Override public void setCancellable(final Cancellable cancellable) { try { if(!releaseTriggerLatch.await(1, TimeUnit.SECONDS)) { throw new RuntimeException("Waited too long..."); } } catch(final InterruptedException ie) { throw new RuntimeException(ie); } super.setCancellable(cancellable); } } } ././@LongLink0100644 0000000 0000000 00000000175 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestBasicConnectionManager.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestBas0100644 0000000 0000000 00000006427 12301751657 032517 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import junit.framework.Assert; import org.apache.http.HttpHost; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.BasicHttpClientConnectionManager; import org.apache.http.localserver.LocalTestServer; import org.apache.http.util.EntityUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.net.InetSocketAddress; public class TestBasicConnectionManager extends IntegrationTestBase { @Before public void setUp() throws Exception { this.localServer = new LocalTestServer(null, null); this.localServer.registerDefaultHandlers(); this.localServer.start(); this.httpclient = HttpClients.custom() .setConnectionManager(new BasicHttpClientConnectionManager()) .build(); } @After public void cleanup() throws IOException { this.httpclient.close(); } @Test public void testBasics() throws Exception { final InetSocketAddress address = localServer.getServiceAddress(); final HttpHost target = new HttpHost(address.getHostName(), address.getPort()); final HttpGet get = new HttpGet("/random/1024"); final CloseableHttpResponse response = this.httpclient.execute(target, get); try { Assert.assertEquals(200, response.getStatusLine().getStatusCode()); EntityUtils.consume(response.getEntity()); } finally { response.close(); } } @Test(expected=IllegalStateException.class) public void testConnectionStillInUse() throws Exception { final InetSocketAddress address = localServer.getServiceAddress(); final HttpHost target = new HttpHost(address.getHostName(), address.getPort()); final HttpGet get1 = new HttpGet("/random/1024"); this.httpclient.execute(target, get1); final HttpGet get2 = new HttpGet("/random/1024"); this.httpclient.execute(target, get2); } } ././@LongLink0100644 0000000 0000000 00000000173 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientAuthentication.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCli0100644 0000000 0000000 00000062464 12301751657 032524 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.concurrent.atomic.AtomicLong; import org.apache.http.Consts; import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpInetConnection; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthCache; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.NonRepeatableRequestException; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.TargetAuthenticationStrategy; import org.apache.http.localserver.BasicAuthTokenExtractor; import org.apache.http.localserver.LocalTestServer; import org.apache.http.localserver.RequestBasicAuth; import org.apache.http.localserver.ResponseBasicUnauthorized; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpCoreContext; import org.apache.http.protocol.HttpExpectationVerifier; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpProcessorBuilder; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.protocol.ResponseConnControl; import org.apache.http.protocol.ResponseContent; import org.apache.http.protocol.ResponseDate; import org.apache.http.protocol.ResponseServer; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * Unit tests for automatic client authentication. */ public class TestClientAuthentication extends IntegrationTestBase { @Before public void setUp() throws Exception { final HttpProcessor httpproc = HttpProcessorBuilder.create() .add(new ResponseDate()) .add(new ResponseServer()) .add(new ResponseContent()) .add(new ResponseConnControl()) .add(new RequestBasicAuth()) .add(new ResponseBasicUnauthorized()).build(); this.localServer = new LocalTestServer(httpproc, null); startServer(); } static class AuthHandler implements HttpRequestHandler { public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final String creds = (String) context.getAttribute("creds"); if (creds == null || !creds.equals("test:test")) { response.setStatusCode(HttpStatus.SC_UNAUTHORIZED); } else { response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("success", Consts.ASCII); response.setEntity(entity); } } } static class AuthExpectationVerifier implements HttpExpectationVerifier { private final BasicAuthTokenExtractor authTokenExtractor; public AuthExpectationVerifier() { super(); this.authTokenExtractor = new BasicAuthTokenExtractor(); } public void verify( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException { final String creds = this.authTokenExtractor.extract(request); if (creds == null || !creds.equals("test:test")) { response.setStatusCode(HttpStatus.SC_UNAUTHORIZED); } else { response.setStatusCode(HttpStatus.SC_CONTINUE); } } } static class TestCredentialsProvider implements CredentialsProvider { private final Credentials creds; private AuthScope authscope; TestCredentialsProvider(final Credentials creds) { super(); this.creds = creds; } public void clear() { } public Credentials getCredentials(final AuthScope authscope) { this.authscope = authscope; return this.creds; } public void setCredentials(final AuthScope authscope, final Credentials credentials) { } public AuthScope getAuthScope() { return this.authscope; } } @Test public void testBasicAuthenticationNoCreds() throws Exception { this.localServer.register("*", new AuthHandler()); final TestCredentialsProvider credsProvider = new TestCredentialsProvider(null); this.httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build(); final HttpGet httpget = new HttpGet("/"); final HttpResponse response = this.httpclient.execute(getServerHttp(), httpget); final HttpEntity entity = response.getEntity(); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode()); Assert.assertNotNull(entity); EntityUtils.consume(entity); final AuthScope authscope = credsProvider.getAuthScope(); Assert.assertNotNull(authscope); Assert.assertEquals("test realm", authscope.getRealm()); } @Test public void testBasicAuthenticationFailure() throws Exception { this.localServer.register("*", new AuthHandler()); final TestCredentialsProvider credsProvider = new TestCredentialsProvider( new UsernamePasswordCredentials("test", "all-wrong")); this.httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build(); final HttpGet httpget = new HttpGet("/"); final HttpResponse response = this.httpclient.execute(getServerHttp(), httpget); final HttpEntity entity = response.getEntity(); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode()); Assert.assertNotNull(entity); EntityUtils.consume(entity); final AuthScope authscope = credsProvider.getAuthScope(); Assert.assertNotNull(authscope); Assert.assertEquals("test realm", authscope.getRealm()); } @Test public void testBasicAuthenticationSuccess() throws Exception { this.localServer.register("*", new AuthHandler()); final TestCredentialsProvider credsProvider = new TestCredentialsProvider( new UsernamePasswordCredentials("test", "test")); this.httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build(); final HttpGet httpget = new HttpGet("/"); final HttpResponse response = this.httpclient.execute(getServerHttp(), httpget); final HttpEntity entity = response.getEntity(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertNotNull(entity); EntityUtils.consume(entity); final AuthScope authscope = credsProvider.getAuthScope(); Assert.assertNotNull(authscope); Assert.assertEquals("test realm", authscope.getRealm()); } @Test public void testBasicAuthenticationSuccessOnNonRepeatablePutExpectContinue() throws Exception { final HttpProcessor httpproc = HttpProcessorBuilder.create() .add(new ResponseDate()) .add(new ResponseServer(LocalTestServer.ORIGIN)) .add(new ResponseContent()) .add(new ResponseConnControl()) .add(new RequestBasicAuth()) .add(new ResponseBasicUnauthorized()).build(); this.localServer = new LocalTestServer( httpproc, null, null, new AuthExpectationVerifier(), null, false); this.localServer.register("*", new AuthHandler()); this.localServer.start(); final TestCredentialsProvider credsProvider = new TestCredentialsProvider( new UsernamePasswordCredentials("test", "test")); this.httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build(); final RequestConfig config = RequestConfig.custom().setExpectContinueEnabled(true).build(); final HttpPut httpput = new HttpPut("/"); httpput.setConfig(config); httpput.setEntity(new InputStreamEntity( new ByteArrayInputStream( new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ), -1)); final HttpResponse response = this.httpclient.execute(getServerHttp(), httpput); final HttpEntity entity = response.getEntity(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertNotNull(entity); } @Test(expected=ClientProtocolException.class) public void testBasicAuthenticationFailureOnNonRepeatablePutDontExpectContinue() throws Exception { this.localServer.register("*", new AuthHandler()); final TestCredentialsProvider credsProvider = new TestCredentialsProvider( new UsernamePasswordCredentials("test", "boom")); this.httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build(); final RequestConfig config = RequestConfig.custom().setExpectContinueEnabled(true).build(); final HttpPut httpput = new HttpPut("/"); httpput.setConfig(config); httpput.setEntity(new InputStreamEntity( new ByteArrayInputStream( new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ), -1)); try { this.httpclient.execute(getServerHttp(), httpput); Assert.fail("ClientProtocolException should have been thrown"); } catch (final ClientProtocolException ex) { final Throwable cause = ex.getCause(); Assert.assertNotNull(cause); Assert.assertTrue(cause instanceof NonRepeatableRequestException); throw ex; } } @Test public void testBasicAuthenticationSuccessOnRepeatablePost() throws Exception { this.localServer.register("*", new AuthHandler()); final TestCredentialsProvider credsProvider = new TestCredentialsProvider( new UsernamePasswordCredentials("test", "test")); this.httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build(); final HttpPost httppost = new HttpPost("/"); httppost.setEntity(new StringEntity("some important stuff", Consts.ASCII)); final HttpResponse response = this.httpclient.execute(getServerHttp(), httppost); final HttpEntity entity = response.getEntity(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertNotNull(entity); EntityUtils.consume(entity); final AuthScope authscope = credsProvider.getAuthScope(); Assert.assertNotNull(authscope); Assert.assertEquals("test realm", authscope.getRealm()); } @Test(expected=ClientProtocolException.class) public void testBasicAuthenticationFailureOnNonRepeatablePost() throws Exception { this.localServer.register("*", new AuthHandler()); final TestCredentialsProvider credsProvider = new TestCredentialsProvider( new UsernamePasswordCredentials("test", "test")); this.httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build(); final HttpPost httppost = new HttpPost("/"); httppost.setEntity(new InputStreamEntity( new ByteArrayInputStream( new byte[] { 0,1,2,3,4,5,6,7,8,9 }), -1)); try { this.httpclient.execute(getServerHttp(), httppost); Assert.fail("ClientProtocolException should have been thrown"); } catch (final ClientProtocolException ex) { final Throwable cause = ex.getCause(); Assert.assertNotNull(cause); Assert.assertTrue(cause instanceof NonRepeatableRequestException); throw ex; } } static class TestTargetAuthenticationStrategy extends TargetAuthenticationStrategy { private final AtomicLong count; public TestTargetAuthenticationStrategy() { super(); this.count = new AtomicLong(); } @Override public boolean isAuthenticationRequested( final HttpHost host, final HttpResponse response, final HttpContext context) { final boolean res = super.isAuthenticationRequested(host, response, context); if (res == true) { this.count.incrementAndGet(); } return res; } public long getCount() { return this.count.get(); } } @Test public void testBasicAuthenticationCredentialsCaching() throws Exception { this.localServer.register("*", new AuthHandler()); final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("test", "test")); final TestTargetAuthenticationStrategy authStrategy = new TestTargetAuthenticationStrategy(); this.httpclient = HttpClients.custom() .setDefaultCredentialsProvider(credsProvider) .setTargetAuthenticationStrategy(authStrategy) .build(); final HttpClientContext context = HttpClientContext.create(); final HttpHost targethost = getServerHttp(); final HttpGet httpget = new HttpGet("/"); final HttpResponse response1 = this.httpclient.execute(targethost, httpget, context); final HttpEntity entity1 = response1.getEntity(); Assert.assertEquals(HttpStatus.SC_OK, response1.getStatusLine().getStatusCode()); Assert.assertNotNull(entity1); EntityUtils.consume(entity1); final HttpResponse response2 = this.httpclient.execute(targethost, httpget, context); final HttpEntity entity2 = response1.getEntity(); Assert.assertEquals(HttpStatus.SC_OK, response2.getStatusLine().getStatusCode()); Assert.assertNotNull(entity2); EntityUtils.consume(entity2); Assert.assertEquals(1, authStrategy.getCount()); } @Test public void testAuthenticationUserinfoInRequestSuccess() throws Exception { this.localServer.register("*", new AuthHandler()); final HttpHost target = getServerHttp(); final HttpGet httpget = new HttpGet("http://test:test@" + target.toHostString() + "/"); this.httpclient = HttpClients.custom().build(); final HttpResponse response = this.httpclient.execute(getServerHttp(), httpget); final HttpEntity entity = response.getEntity(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertNotNull(entity); EntityUtils.consume(entity); } @Test public void testAuthenticationUserinfoInRequestFailure() throws Exception { this.localServer.register("*", new AuthHandler()); final HttpHost target = getServerHttp(); final HttpGet httpget = new HttpGet("http://test:all-wrong@" + target.toHostString() + "/"); this.httpclient = HttpClients.custom().build(); final HttpResponse response = this.httpclient.execute(getServerHttp(), httpget); final HttpEntity entity = response.getEntity(); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode()); Assert.assertNotNull(entity); EntityUtils.consume(entity); } private static class RedirectHandler implements HttpRequestHandler { public RedirectHandler() { super(); } public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final HttpInetConnection conn = (HttpInetConnection) context.getAttribute(HttpCoreContext.HTTP_CONNECTION); final String localhost = conn.getLocalAddress().getHostName(); final int port = conn.getLocalPort(); response.setStatusCode(HttpStatus.SC_MOVED_PERMANENTLY); response.addHeader(new BasicHeader("Location", "http://test:test@" + localhost + ":" + port + "/")); } } @Test public void testAuthenticationUserinfoInRedirectSuccess() throws Exception { this.localServer.register("*", new AuthHandler()); this.localServer.register("/thatway", new RedirectHandler()); final HttpHost target = getServerHttp(); final HttpGet httpget = new HttpGet("http://" + target.toHostString() + "/thatway"); this.httpclient = HttpClients.custom().build(); final HttpResponse response = this.httpclient.execute(getServerHttp(), httpget); final HttpEntity entity = response.getEntity(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertNotNull(entity); EntityUtils.consume(entity); } static class CountingAuthHandler implements HttpRequestHandler { private final AtomicLong count; public CountingAuthHandler() { super(); this.count = new AtomicLong(); } public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { this.count.incrementAndGet(); final String creds = (String) context.getAttribute("creds"); if (creds == null || !creds.equals("test:test")) { response.setStatusCode(HttpStatus.SC_UNAUTHORIZED); } else { response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("success", Consts.ASCII); response.setEntity(entity); } } public long getCount() { return this.count.get(); } } @Test public void testPreemptiveAuthentication() throws Exception { final CountingAuthHandler requestHandler = new CountingAuthHandler(); this.localServer.register("*", requestHandler); final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("test", "test")); this.httpclient = HttpClients.custom() .setDefaultCredentialsProvider(credsProvider) .build(); final HttpHost targethost = getServerHttp(); final HttpClientContext context = HttpClientContext.create(); final AuthCache authCache = new BasicAuthCache(); authCache.put(targethost, new BasicScheme()); context.setAuthCache(authCache); final HttpGet httpget = new HttpGet("/"); final HttpResponse response1 = this.httpclient.execute(targethost, httpget, context); final HttpEntity entity1 = response1.getEntity(); Assert.assertEquals(HttpStatus.SC_OK, response1.getStatusLine().getStatusCode()); Assert.assertNotNull(entity1); EntityUtils.consume(entity1); Assert.assertEquals(1, requestHandler.getCount()); } @Test public void testPreemptiveAuthenticationFailure() throws Exception { final CountingAuthHandler requestHandler = new CountingAuthHandler(); this.localServer.register("*", requestHandler); final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("test", "stuff")); this.httpclient = HttpClients.custom() .setDefaultCredentialsProvider(credsProvider) .build(); final HttpHost targethost = getServerHttp(); final HttpClientContext context = HttpClientContext.create(); final AuthCache authCache = new BasicAuthCache(); authCache.put(targethost, new BasicScheme()); context.setAuthCache(authCache); final HttpGet httpget = new HttpGet("/"); final HttpResponse response1 = this.httpclient.execute(targethost, httpget, context); final HttpEntity entity1 = response1.getEntity(); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response1.getStatusLine().getStatusCode()); Assert.assertNotNull(entity1); EntityUtils.consume(entity1); Assert.assertEquals(1, requestHandler.getCount()); } static class ProxyAuthHandler implements HttpRequestHandler { public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final String creds = (String) context.getAttribute("creds"); if (creds == null || !creds.equals("test:test")) { response.setStatusCode(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED); } else { response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("success", Consts.ASCII); response.setEntity(entity); } } } @Test public void testAuthenticationTargetAsProxy() throws Exception { this.localServer.register("*", new ProxyAuthHandler()); final TestCredentialsProvider credsProvider = new TestCredentialsProvider(null); this.httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build(); final HttpGet httpget = new HttpGet("/"); final HttpResponse response = this.httpclient.execute(getServerHttp(), httpget); final HttpEntity entity = response.getEntity(); Assert.assertEquals(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED, response.getStatusLine().getStatusCode()); EntityUtils.consume(entity); } static class ClosingAuthHandler implements HttpRequestHandler { public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final String creds = (String) context.getAttribute("creds"); if (creds == null || !creds.equals("test:test")) { response.setStatusCode(HttpStatus.SC_UNAUTHORIZED); } else { response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("success", Consts.ASCII); response.setEntity(entity); response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); } } } @Test public void testConnectionCloseAfterAuthenticationSuccess() throws Exception { this.localServer.register("*", new ClosingAuthHandler()); final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("test", "test")); this.httpclient = HttpClients.custom() .setDefaultCredentialsProvider(credsProvider) .build(); final HttpClientContext context = HttpClientContext.create(); final HttpHost targethost = getServerHttp(); for (int i = 0; i < 2; i++) { final HttpGet httpget = new HttpGet("/"); final HttpResponse response = this.httpclient.execute(targethost, httpget, context); EntityUtils.consume(response.getEntity()); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); } } } ././@LongLink0100644 0000000 0000000 00000000203 12302131605 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientAuthenticationFakeNTLM.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCli0100644 0000000 0000000 00000024111 12301751657 032507 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import org.apache.http.HttpException; import org.apache.http.HttpHeaders; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.auth.AuthScope; import org.apache.http.auth.NTCredentials; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.HttpClients; import org.apache.http.localserver.LocalTestServer; import org.apache.http.message.BasicStatusLine; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.io.IOException; /** * Unit tests for some of the NTLM auth functionality.. */ public class TestClientAuthenticationFakeNTLM extends IntegrationTestBase { @Before public void setUp() throws Exception { this.localServer = new LocalTestServer(null, null); } static class NtlmResponseHandler implements HttpRequestHandler { public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { response.setStatusLine(new BasicStatusLine( HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "Authentication Required")); response.setHeader("Connection", "Keep-Alive"); response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM"); } } @Test public void testNTLMAuthenticationFailure() throws Exception { this.localServer.register("*", new NtlmResponseHandler()); this.localServer.start(); final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(AuthScope.ANY, new NTCredentials("test", "test", null, null)); this.httpclient = HttpClients.custom() .setDefaultCredentialsProvider(credsProvider) .build(); final HttpContext context = HttpClientContext.create(); final HttpHost targethost = getServerHttp(); final HttpGet httpget = new HttpGet("/"); final HttpResponse response = this.httpclient.execute(targethost, httpget, context); EntityUtils.consume(response.getEntity()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode()); } static class NtlmType2MessageResponseHandler implements HttpRequestHandler { private final String authenticateHeaderValue; public NtlmType2MessageResponseHandler(final String type2Message) { this.authenticateHeaderValue = "NTLM " + type2Message; } public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { response.setStatusLine(new BasicStatusLine( HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "Authentication Required")); response.setHeader("Connection", "Keep-Alive"); if (!request.containsHeader(HttpHeaders.AUTHORIZATION)) { response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM"); } else { response.setHeader(HttpHeaders.WWW_AUTHENTICATE, authenticateHeaderValue); } } } @Test public void testNTLMv1Type2Message() throws Exception { this.localServer.register("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" + "AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" + "AGUAcgB2AGUAcgA=")); this.localServer.start(); final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(AuthScope.ANY, new NTCredentials("test", "test", null, null)); this.httpclient = HttpClients.custom() .setDefaultCredentialsProvider(credsProvider) .build(); final HttpContext context = HttpClientContext.create(); final HttpHost targethost = getServerHttp(); final HttpGet httpget = new HttpGet("/"); final HttpResponse response = this.httpclient.execute(targethost, httpget, context); EntityUtils.consume(response.getEntity()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode()); } @Test public void testNTLMv2Type2Message() throws Exception { this.localServer.register("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" + "AADAAMADgAAAAzgoriASNFZ4mrze8AAAAAAAAAACQAJABEAAAABgBwFwAAAA9T" + "AGUAcgB2AGUAcgACAAwARABvAG0AYQBpAG4AAQAMAFMAZQByAHYAZQByAAAAAAA=")); this.localServer.start(); final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(AuthScope.ANY, new NTCredentials("test", "test", null, null)); this.httpclient = HttpClients.custom() .setDefaultCredentialsProvider(credsProvider) .build(); final HttpContext context = HttpClientContext.create(); final HttpHost targethost = getServerHttp(); final HttpGet httpget = new HttpGet("/"); final HttpResponse response = this.httpclient.execute(targethost, httpget, context); EntityUtils.consume(response.getEntity()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode()); } static class NtlmType2MessageOnlyResponseHandler implements HttpRequestHandler { private final String authenticateHeaderValue; public NtlmType2MessageOnlyResponseHandler(final String type2Message) { this.authenticateHeaderValue = "NTLM " + type2Message; } public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { response.setStatusLine(new BasicStatusLine( HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "Authentication Required")); response.setHeader("Connection", "Keep-Alive"); response.setHeader(HttpHeaders.WWW_AUTHENTICATE, authenticateHeaderValue); } } @Test public void testNTLMType2MessageOnlyAuthenticationFailure() throws Exception { this.localServer.register("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" + "AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" + "AGUAcgB2AGUAcgA=")); this.localServer.start(); final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(AuthScope.ANY, new NTCredentials("test", "test", null, null)); this.httpclient = HttpClients.custom() .setDefaultCredentialsProvider(credsProvider) .build(); final HttpContext context = HttpClientContext.create(); final HttpHost targethost = getServerHttp(); final HttpGet httpget = new HttpGet("/"); final HttpResponse response = this.httpclient.execute(targethost, httpget, context); EntityUtils.consume(response.getEntity()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode()); } @Test public void testNTLMType2NonUnicodeMessageOnlyAuthenticationFailure() throws Exception { this.localServer.register("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" + "AABgAGADgAAAAyggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" + "ZXJ2ZXI=")); this.localServer.start(); final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(AuthScope.ANY, new NTCredentials("test", "test", null, null)); this.httpclient = HttpClients.custom() .setDefaultCredentialsProvider(credsProvider) .build(); final HttpContext context = HttpClientContext.create(); final HttpHost targethost = getServerHttp(); final HttpGet httpget = new HttpGet("/"); final HttpResponse response = this.httpclient.execute(targethost, httpget, context); EntityUtils.consume(response.getEntity()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode()); } } ././@LongLink0100644 0000000 0000000 00000000203 12302131605 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientAuthenticationFallBack.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCli0100644 0000000 0000000 00000013424 12301751657 032514 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.IOException; import org.apache.http.Consts; import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseInterceptor; import org.apache.http.HttpStatus; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.HttpGet; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClients; import org.apache.http.localserver.LocalTestServer; import org.apache.http.localserver.RequestBasicAuth; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpProcessorBuilder; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.protocol.ResponseConnControl; import org.apache.http.protocol.ResponseContent; import org.apache.http.protocol.ResponseDate; import org.apache.http.protocol.ResponseServer; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestClientAuthenticationFallBack extends IntegrationTestBase { public class ResponseBasicUnauthorized implements HttpResponseInterceptor { public void process( final HttpResponse response, final HttpContext context) throws HttpException, IOException { if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { response.addHeader(AUTH.WWW_AUTH, "Digest realm=\"test realm\" invalid"); response.addHeader(AUTH.WWW_AUTH, "Basic realm=\"test realm\""); } } } @Before public void setUp() throws Exception { final HttpProcessor httpproc = HttpProcessorBuilder.create() .add(new ResponseDate()) .add(new ResponseServer(LocalTestServer.ORIGIN)) .add(new ResponseContent()) .add(new ResponseConnControl()) .add(new RequestBasicAuth()) .add(new ResponseBasicUnauthorized()).build(); this.localServer = new LocalTestServer(httpproc, null); startServer(); } static class AuthHandler implements HttpRequestHandler { public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final String creds = (String) context.getAttribute("creds"); if (creds == null || !creds.equals("test:test")) { response.setStatusCode(HttpStatus.SC_UNAUTHORIZED); } else { response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("success", Consts.ASCII); response.setEntity(entity); } } } static class TestCredentialsProvider implements CredentialsProvider { private final Credentials creds; private AuthScope authscope; TestCredentialsProvider(final Credentials creds) { super(); this.creds = creds; } public void clear() { } public Credentials getCredentials(final AuthScope authscope) { this.authscope = authscope; return this.creds; } public void setCredentials(final AuthScope authscope, final Credentials credentials) { } public AuthScope getAuthScope() { return this.authscope; } } @Test public void testBasicAuthenticationSuccess() throws Exception { this.localServer.register("*", new AuthHandler()); final TestCredentialsProvider credsProvider = new TestCredentialsProvider( new UsernamePasswordCredentials("test", "test")); this.httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build(); final HttpGet httpget = new HttpGet("/"); final HttpResponse response = this.httpclient.execute(getServerHttp(), httpget); final HttpEntity entity = response.getEntity(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertNotNull(entity); EntityUtils.consume(entity); final AuthScope authscope = credsProvider.getAuthScope(); Assert.assertNotNull(authscope); Assert.assertEquals("test realm", authscope.getRealm()); } } ././@LongLink0100644 0000000 0000000 00000000175 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientReauthentication.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCli0100644 0000000 0000000 00000017302 12301751657 032513 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.IOException; import java.util.Arrays; import java.util.concurrent.atomic.AtomicLong; import org.apache.http.Consts; import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseInterceptor; import org.apache.http.HttpStatus; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.entity.StringEntity; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.auth.BasicSchemeFactory; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.TargetAuthenticationStrategy; import org.apache.http.localserver.LocalTestServer; import org.apache.http.localserver.RequestBasicAuth; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpProcessorBuilder; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.protocol.ResponseConnControl; import org.apache.http.protocol.ResponseContent; import org.apache.http.protocol.ResponseDate; import org.apache.http.protocol.ResponseServer; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestClientReauthentication extends IntegrationTestBase { public class ResponseBasicUnauthorized implements HttpResponseInterceptor { public void process( final HttpResponse response, final HttpContext context) throws HttpException, IOException { if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { response.addHeader(AUTH.WWW_AUTH, "MyBasic realm=\"test realm\""); } } } @Before public void setUp() throws Exception { final HttpProcessor httpproc = HttpProcessorBuilder.create() .add(new ResponseDate()) .add(new ResponseServer(LocalTestServer.ORIGIN)) .add(new ResponseContent()) .add(new ResponseConnControl()) .add(new RequestBasicAuth()) .add(new ResponseBasicUnauthorized()).build(); this.localServer = new LocalTestServer(httpproc, null); startServer(); } static class AuthHandler implements HttpRequestHandler { private final AtomicLong count = new AtomicLong(0); public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final String creds = (String) context.getAttribute("creds"); if (creds == null || !creds.equals("test:test")) { response.setStatusCode(HttpStatus.SC_UNAUTHORIZED); } else { // Make client re-authenticate on each fourth request if (this.count.incrementAndGet() % 4 == 0) { response.setStatusCode(HttpStatus.SC_UNAUTHORIZED); } else { response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("success", Consts.ASCII); response.setEntity(entity); } } } } static class TestCredentialsProvider implements CredentialsProvider { private final Credentials creds; private AuthScope authscope; TestCredentialsProvider(final Credentials creds) { super(); this.creds = creds; } public void clear() { } public Credentials getCredentials(final AuthScope authscope) { this.authscope = authscope; return this.creds; } public void setCredentials(final AuthScope authscope, final Credentials credentials) { } public AuthScope getAuthScope() { return this.authscope; } } @Test public void testBasicAuthenticationSuccess() throws Exception { this.localServer.register("*", new AuthHandler()); final BasicSchemeFactory myBasicAuthSchemeFactory = new BasicSchemeFactory() { @Override public AuthScheme create(final HttpContext context) { return new BasicScheme() { @Override public String getSchemeName() { return "MyBasic"; } }; } }; final TargetAuthenticationStrategy myAuthStrategy = new TargetAuthenticationStrategy() { @Override protected boolean isCachable(final AuthScheme authScheme) { return "MyBasic".equalsIgnoreCase(authScheme.getSchemeName()); } }; final TestCredentialsProvider credsProvider = new TestCredentialsProvider( new UsernamePasswordCredentials("test", "test")); final RequestConfig config = RequestConfig.custom() .setTargetPreferredAuthSchemes(Arrays.asList("MyBasic")) .build(); final Registry authSchemeRegistry = RegistryBuilder.create() .register("MyBasic", myBasicAuthSchemeFactory) .build(); this.httpclient = HttpClients.custom() .setDefaultAuthSchemeRegistry(authSchemeRegistry) .setTargetAuthenticationStrategy(myAuthStrategy) .setDefaultCredentialsProvider(credsProvider) .build(); final HttpClientContext context = HttpClientContext.create(); for (int i = 0; i < 10; i++) { final HttpGet httpget = new HttpGet("/"); httpget.setConfig(config); final HttpResponse response = this.httpclient.execute(getServerHttp(), httpget, context); final HttpEntity entity = response.getEntity(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertNotNull(entity); EntityUtils.consume(entity); } } } ././@LongLink0100644 0000000 0000000 00000000175 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCli0100644 0000000 0000000 00000024032 12301751656 032510 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URI; import java.util.List; import org.apache.http.Header; import org.apache.http.HttpClientConnection; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.NonRepeatableRequestException; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.URIBuilder; import org.apache.http.client.utils.URIUtils; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestExecutor; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * Client protocol handling tests. */ public class TestClientRequestExecution extends IntegrationTestBase { @Before public void setUp() throws Exception { startServer(); } private static class SimpleService implements HttpRequestHandler { public SimpleService() { super(); } public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("Whatever"); response.setEntity(entity); } } private static class FaultyHttpRequestExecutor extends HttpRequestExecutor { private static final String MARKER = "marker"; private final String failureMsg; public FaultyHttpRequestExecutor(final String failureMsg) { this.failureMsg = failureMsg; } @Override public HttpResponse execute( final HttpRequest request, final HttpClientConnection conn, final HttpContext context) throws IOException, HttpException { final HttpResponse response = super.execute(request, conn, context); final Object marker = context.getAttribute(MARKER); if (marker == null) { context.setAttribute(MARKER, Boolean.TRUE); throw new IOException(failureMsg); } return response; } } @Test public void testAutoGeneratedHeaders() throws Exception { final int port = this.localServer.getServiceAddress().getPort(); this.localServer.register("*", new SimpleService()); final HttpRequestInterceptor interceptor = new HttpRequestInterceptor() { public void process( final HttpRequest request, final HttpContext context) throws HttpException, IOException { request.addHeader("my-header", "stuff"); } }; final HttpRequestRetryHandler requestRetryHandler = new HttpRequestRetryHandler() { public boolean retryRequest( final IOException exception, final int executionCount, final HttpContext context) { return true; } }; this.httpclient = HttpClients.custom() .addInterceptorFirst(interceptor) .setRequestExecutor(new FaultyHttpRequestExecutor("Oppsie")) .setRetryHandler(requestRetryHandler) .build(); final HttpClientContext context = HttpClientContext.create(); final String s = "http://localhost:" + port; final HttpGet httpget = new HttpGet(s); final HttpResponse response = this.httpclient.execute(getServerHttp(), httpget, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); final Header[] myheaders = reqWrapper.getHeaders("my-header"); Assert.assertNotNull(myheaders); Assert.assertEquals(1, myheaders.length); } @Test(expected=ClientProtocolException.class) public void testNonRepeatableEntity() throws Exception { final int port = this.localServer.getServiceAddress().getPort(); this.localServer.register("*", new SimpleService()); final HttpRequestRetryHandler requestRetryHandler = new HttpRequestRetryHandler() { public boolean retryRequest( final IOException exception, final int executionCount, final HttpContext context) { return true; } }; this.httpclient = HttpClients.custom() .setRequestExecutor(new FaultyHttpRequestExecutor("a message showing that this failed")) .setRetryHandler(requestRetryHandler) .build(); final HttpClientContext context = HttpClientContext.create(); final String s = "http://localhost:" + port; final HttpPost httppost = new HttpPost(s); httppost.setEntity(new InputStreamEntity( new ByteArrayInputStream( new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ), -1)); try { this.httpclient.execute(getServerHttp(), httppost, context); } catch (final ClientProtocolException ex) { Assert.assertTrue(ex.getCause() instanceof NonRepeatableRequestException); final NonRepeatableRequestException nonRepeat = (NonRepeatableRequestException)ex.getCause(); Assert.assertTrue(nonRepeat.getCause() instanceof IOException); Assert.assertEquals("a message showing that this failed", nonRepeat.getCause().getMessage()); throw ex; } } @Test public void testNonCompliantURI() throws Exception { this.localServer.register("*", new SimpleService()); this.httpclient = HttpClients.createDefault(); final HttpClientContext context = HttpClientContext.create(); final BasicHttpRequest request = new BasicHttpRequest("GET", "blah.:.blah.:."); final HttpResponse response = this.httpclient.execute(getServerHttp(), request, context); EntityUtils.consume(response.getEntity()); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); final HttpRequest reqWrapper = context.getRequest(); Assert.assertEquals("blah.:.blah.:.", reqWrapper.getRequestLine().getUri()); } @Test public void testRelativeRequestURIWithFragment() throws Exception { this.localServer.register("*", new SimpleService()); this.httpclient = HttpClients.createDefault(); final HttpHost target = getServerHttp(); final HttpGet httpget = new HttpGet("/stuff#blahblah"); final HttpClientContext context = HttpClientContext.create(); final HttpResponse response = this.httpclient.execute(target, httpget, context); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); EntityUtils.consume(response.getEntity()); final HttpRequest request = context.getRequest(); Assert.assertEquals("/stuff", request.getRequestLine().getUri()); } @Test public void testAbsoluteRequestURIWithFragment() throws Exception { this.localServer.register("*", new SimpleService()); this.httpclient = HttpClients.createDefault(); final HttpHost target = getServerHttp(); final URI uri = new URIBuilder() .setHost(target.getHostName()) .setPort(target.getPort()) .setScheme(target.getSchemeName()) .setPath("/stuff") .setFragment("blahblah") .build(); final HttpGet httpget = new HttpGet(uri); final HttpClientContext context = HttpClientContext.create(); final HttpResponse response = this.httpclient.execute(httpget, context); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); EntityUtils.consume(response.getEntity()); final HttpRequest request = context.getRequest(); Assert.assertEquals("/stuff", request.getRequestLine().getUri()); final List redirectLocations = context.getRedirectLocations(); final URI location = URIUtils.resolve(uri, target, redirectLocations); Assert.assertEquals(uri, location); } } ././@LongLink0100644 0000000 0000000 00000000174 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestConnectionAutoRelease.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCon0100644 0000000 0000000 00000023002 12301751657 032515 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.concurrent.TimeUnit; import org.apache.http.HttpClientConnection; import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.MalformedChunkCodingException; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.ConnectionPoolTimeoutException; import org.apache.http.conn.ConnectionRequest; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.entity.BasicHttpEntity; import org.apache.http.impl.DefaultBHttpServerConnection; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.pool.PoolStats; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpCoreContext; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestConnectionAutoRelease extends IntegrationTestBase { private PoolingHttpClientConnectionManager mgr; @Before public void setUp() throws Exception { startServer(); this.mgr = new PoolingHttpClientConnectionManager(); this.httpclient = HttpClients.custom().setConnectionManager(this.mgr).build(); } @Test public void testReleaseOnEntityConsumeContent() throws Exception { this.mgr.setDefaultMaxPerRoute(1); this.mgr.setMaxTotal(1); // Zero connections in the pool PoolStats stats = this.mgr.getTotalStats(); Assert.assertEquals(0, stats.getAvailable()); // Get some random data final HttpGet httpget = new HttpGet("/random/20000"); final HttpHost target = getServerHttp(); final HttpResponse response = this.httpclient.execute(target, httpget); ConnectionRequest connreq = this.mgr.requestConnection(new HttpRoute(target), null); try { connreq.get(250, TimeUnit.MILLISECONDS); Assert.fail("ConnectionPoolTimeoutException should have been thrown"); } catch (final ConnectionPoolTimeoutException expected) { } final HttpEntity e = response.getEntity(); Assert.assertNotNull(e); EntityUtils.consume(e); // Expect one connection in the pool stats = this.mgr.getTotalStats(); Assert.assertEquals(1, stats.getAvailable()); // Make sure one connection is available connreq = this.mgr.requestConnection(new HttpRoute(target), null); final HttpClientConnection conn = connreq.get(250, TimeUnit.MILLISECONDS); this.mgr.releaseConnection(conn, null, -1, null); } @Test public void testReleaseOnEntityWriteTo() throws Exception { this.mgr.setDefaultMaxPerRoute(1); this.mgr.setMaxTotal(1); // Zero connections in the pool PoolStats stats = this.mgr.getTotalStats(); Assert.assertEquals(0, stats.getAvailable()); // Get some random data final HttpGet httpget = new HttpGet("/random/20000"); final HttpHost target = getServerHttp(); final HttpResponse response = this.httpclient.execute(target, httpget); ConnectionRequest connreq = this.mgr.requestConnection(new HttpRoute(target), null); try { connreq.get(250, TimeUnit.MILLISECONDS); Assert.fail("ConnectionPoolTimeoutException should have been thrown"); } catch (final ConnectionPoolTimeoutException expected) { } final HttpEntity e = response.getEntity(); Assert.assertNotNull(e); final ByteArrayOutputStream outsteam = new ByteArrayOutputStream(); e.writeTo(outsteam); // Expect one connection in the pool stats = this.mgr.getTotalStats(); Assert.assertEquals(1, stats.getAvailable()); // Make sure one connection is available connreq = this.mgr.requestConnection(new HttpRoute(target), null); final HttpClientConnection conn = connreq.get(250, TimeUnit.MILLISECONDS); this.mgr.releaseConnection(conn, null, -1, null); } @Test public void testReleaseOnAbort() throws Exception { this.mgr.setDefaultMaxPerRoute(1); this.mgr.setMaxTotal(1); // Zero connections in the pool final PoolStats stats = this.mgr.getTotalStats(); Assert.assertEquals(0, stats.getAvailable()); // Get some random data final HttpGet httpget = new HttpGet("/random/20000"); final HttpHost target = getServerHttp(); final HttpResponse response = this.httpclient.execute(target, httpget); ConnectionRequest connreq = this.mgr.requestConnection(new HttpRoute(target), null); try { connreq.get(250, TimeUnit.MILLISECONDS); Assert.fail("ConnectionPoolTimeoutException should have been thrown"); } catch (final ConnectionPoolTimeoutException expected) { } final HttpEntity e = response.getEntity(); Assert.assertNotNull(e); httpget.abort(); // Expect zero connections in the pool Assert.assertEquals(0, this.mgr.getTotalStats().getAvailable()); // Make sure one connection is available connreq = this.mgr.requestConnection(new HttpRoute(target), null); final HttpClientConnection conn = connreq.get(250, TimeUnit.MILLISECONDS); this.mgr.releaseConnection(conn, null, -1, null); } @Test public void testReleaseOnIOException() throws Exception { this.localServer.register("/dropdead", new HttpRequestHandler() { public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final BasicHttpEntity entity = new BasicHttpEntity() { @Override public void writeTo( final OutputStream outstream) throws IOException { final byte[] tmp = new byte[5]; outstream.write(tmp); outstream.flush(); // do something comletely ugly in order to trigger // MalformedChunkCodingException final DefaultBHttpServerConnection conn = (DefaultBHttpServerConnection) context.getAttribute(HttpCoreContext.HTTP_CONNECTION); try { conn.sendResponseHeader(response); } catch (final HttpException ignore) { } } } ; entity.setChunked(true); response.setEntity(entity); } }); this.mgr.setDefaultMaxPerRoute(1); this.mgr.setMaxTotal(1); // Zero connections in the pool Assert.assertEquals(0, this.mgr.getTotalStats().getAvailable()); // Get some random data final HttpGet httpget = new HttpGet("/dropdead"); final HttpHost target = getServerHttp(); final HttpResponse response = this.httpclient.execute(target, httpget); ConnectionRequest connreq = this.mgr.requestConnection(new HttpRoute(target), null); try { connreq.get(250, TimeUnit.MILLISECONDS); Assert.fail("ConnectionPoolTimeoutException should have been thrown"); } catch (final ConnectionPoolTimeoutException expected) { } final HttpEntity e = response.getEntity(); Assert.assertNotNull(e); // Read the content try { EntityUtils.toByteArray(e); Assert.fail("MalformedChunkCodingException should have been thrown"); } catch (final MalformedChunkCodingException expected) { } // Expect zero connections in the pool Assert.assertEquals(0, this.mgr.getTotalStats().getAvailable()); // Make sure one connection is available connreq = this.mgr.requestConnection(new HttpRoute(target), null); final HttpClientConnection conn = connreq.get(250, TimeUnit.MILLISECONDS); this.mgr.releaseConnection(conn, null, -1, null); } } ././@LongLink0100644 0000000 0000000 00000000173 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestConnectionManagement.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCon0100644 0000000 0000000 00000066034 12301751657 032531 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import org.apache.http.HttpClientConnection; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.ConnectionPoolTimeoutException; import org.apache.http.conn.ConnectionRequest; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.localserver.LocalServerTestBase; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpCoreContext; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpRequestExecutor; import org.apache.http.protocol.ImmutableHttpProcessor; import org.apache.http.protocol.RequestConnControl; import org.apache.http.protocol.RequestContent; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * Tests for PoolingHttpClientConnectionManager that do require a server * to communicate with. */ public class TestConnectionManagement extends LocalServerTestBase { @Before public void setup() throws Exception { startServer(); } private static HttpClientConnection getConnection( final HttpClientConnectionManager mgr, final HttpRoute route, final long timeout, final TimeUnit unit) throws ConnectionPoolTimeoutException, ExecutionException, InterruptedException { final ConnectionRequest connRequest = mgr.requestConnection(route, null); return connRequest.get(timeout, unit); } private static HttpClientConnection getConnection( final HttpClientConnectionManager mgr, final HttpRoute route) throws ConnectionPoolTimeoutException, ExecutionException, InterruptedException { final ConnectionRequest connRequest = mgr.requestConnection(route, null); return connRequest.get(0, TimeUnit.MILLISECONDS); } /** * Tests releasing and re-using a connection after a response is read. */ @Test public void testReleaseConnection() throws Exception { final PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager(); mgr.setMaxTotal(1); final HttpHost target = getServerHttp(); final HttpRoute route = new HttpRoute(target, null, false); final int rsplen = 8; final String uri = "/random/" + rsplen; final HttpRequest request = new BasicHttpRequest("GET", uri, HttpVersion.HTTP_1_1); final HttpContext context = new BasicHttpContext(); HttpClientConnection conn = getConnection(mgr, route); mgr.connect(conn, route, 0, context); mgr.routeComplete(conn, route, context); context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, target); final HttpProcessor httpProcessor = new ImmutableHttpProcessor( new HttpRequestInterceptor[] { new RequestContent(), new RequestConnControl() }); final HttpRequestExecutor exec = new HttpRequestExecutor(); exec.preProcess(request, httpProcessor, context); HttpResponse response = exec.execute(request, conn, context); Assert.assertEquals("wrong status in first response", HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); byte[] data = EntityUtils.toByteArray(response.getEntity()); Assert.assertEquals("wrong length of first response entity", rsplen, data.length); // ignore data, but it must be read // check that there is no auto-release by default try { // this should fail quickly, connection has not been released getConnection(mgr, route, 10L, TimeUnit.MILLISECONDS); Assert.fail("ConnectionPoolTimeoutException should have been thrown"); } catch (final ConnectionPoolTimeoutException e) { // expected } conn.close(); mgr.releaseConnection(conn, null, -1, null); conn = getConnection(mgr, route); Assert.assertFalse("connection should have been closed", conn.isOpen()); mgr.connect(conn, route, 0, context); mgr.routeComplete(conn, route, context); // repeat the communication, no need to prepare the request again context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); response = exec.execute(request, conn, context); Assert.assertEquals("wrong status in second response", HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); data = EntityUtils.toByteArray(response.getEntity()); Assert.assertEquals("wrong length of second response entity", rsplen, data.length); // ignore data, but it must be read // release connection after marking it for re-use // expect the next connection obtained to be open mgr.releaseConnection(conn, null, -1, null); conn = getConnection(mgr, route); Assert.assertTrue("connection should have been open", conn.isOpen()); // repeat the communication, no need to prepare the request again context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); response = exec.execute(request, conn, context); Assert.assertEquals("wrong status in third response", HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); data = EntityUtils.toByteArray(response.getEntity()); Assert.assertEquals("wrong length of third response entity", rsplen, data.length); // ignore data, but it must be read mgr.releaseConnection(conn, null, -1, null); mgr.shutdown(); } /** * Tests releasing with time limits. */ @Test public void testReleaseConnectionWithTimeLimits() throws Exception { final PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager(); mgr.setMaxTotal(1); final HttpHost target = getServerHttp(); final HttpRoute route = new HttpRoute(target, null, false); final int rsplen = 8; final String uri = "/random/" + rsplen; final HttpRequest request = new BasicHttpRequest("GET", uri, HttpVersion.HTTP_1_1); final HttpContext context = new BasicHttpContext(); HttpClientConnection conn = getConnection(mgr, route); mgr.connect(conn, route, 0, context); mgr.routeComplete(conn, route, context); context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, target); final HttpProcessor httpProcessor = new ImmutableHttpProcessor( new HttpRequestInterceptor[] { new RequestContent(), new RequestConnControl() }); final HttpRequestExecutor exec = new HttpRequestExecutor(); exec.preProcess(request, httpProcessor, context); HttpResponse response = exec.execute(request, conn, context); Assert.assertEquals("wrong status in first response", HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); byte[] data = EntityUtils.toByteArray(response.getEntity()); Assert.assertEquals("wrong length of first response entity", rsplen, data.length); // ignore data, but it must be read // check that there is no auto-release by default try { // this should fail quickly, connection has not been released getConnection(mgr, route, 10L, TimeUnit.MILLISECONDS); Assert.fail("ConnectionPoolTimeoutException should have been thrown"); } catch (final ConnectionPoolTimeoutException e) { // expected } conn.close(); mgr.releaseConnection(conn, null, 100, TimeUnit.MILLISECONDS); conn = getConnection(mgr, route); Assert.assertFalse("connection should have been closed", conn.isOpen()); // repeat the communication, no need to prepare the request again mgr.connect(conn, route, 0, context); mgr.routeComplete(conn, route, context); context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); response = exec.execute(request, conn, context); Assert.assertEquals("wrong status in second response", HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); data = EntityUtils.toByteArray(response.getEntity()); Assert.assertEquals("wrong length of second response entity", rsplen, data.length); // ignore data, but it must be read mgr.releaseConnection(conn, null, 100, TimeUnit.MILLISECONDS); conn = getConnection(mgr, route); Assert.assertTrue("connection should have been open", conn.isOpen()); // repeat the communication, no need to prepare the request again context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); response = exec.execute(request, conn, context); Assert.assertEquals("wrong status in third response", HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); data = EntityUtils.toByteArray(response.getEntity()); Assert.assertEquals("wrong length of third response entity", rsplen, data.length); // ignore data, but it must be read mgr.releaseConnection(conn, null, 100, TimeUnit.MILLISECONDS); Thread.sleep(150); conn = getConnection(mgr, route); Assert.assertTrue("connection should have been closed", !conn.isOpen()); // repeat the communication, no need to prepare the request again mgr.connect(conn, route, 0, context); mgr.routeComplete(conn, route, context); context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); response = exec.execute(request, conn, context); Assert.assertEquals("wrong status in third response", HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); data = EntityUtils.toByteArray(response.getEntity()); Assert.assertEquals("wrong length of fourth response entity", rsplen, data.length); // ignore data, but it must be read mgr.shutdown(); } @Test public void testCloseExpiredIdleConnections() throws Exception { final PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager(); mgr.setMaxTotal(1); final HttpHost target = getServerHttp(); final HttpRoute route = new HttpRoute(target, null, false); final HttpContext context = new BasicHttpContext(); final HttpClientConnection conn = getConnection(mgr, route); mgr.connect(conn, route, 0, context); mgr.routeComplete(conn, route, context); Assert.assertEquals(1, mgr.getTotalStats().getLeased()); Assert.assertEquals(1, mgr.getStats(route).getLeased()); mgr.releaseConnection(conn, null, 100, TimeUnit.MILLISECONDS); // Released, still active. Assert.assertEquals(1, mgr.getTotalStats().getAvailable()); Assert.assertEquals(1, mgr.getStats(route).getAvailable()); mgr.closeExpiredConnections(); // Time has not expired yet. Assert.assertEquals(1, mgr.getTotalStats().getAvailable()); Assert.assertEquals(1, mgr.getStats(route).getAvailable()); Thread.sleep(150); mgr.closeExpiredConnections(); // Time expired now, connections are destroyed. Assert.assertEquals(0, mgr.getTotalStats().getAvailable()); Assert.assertEquals(0, mgr.getStats(route).getAvailable()); mgr.shutdown(); } @Test public void testCloseExpiredTTLConnections() throws Exception { final PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager( 100, TimeUnit.MILLISECONDS); mgr.setMaxTotal(1); final HttpHost target = getServerHttp(); final HttpRoute route = new HttpRoute(target, null, false); final HttpContext context = new BasicHttpContext(); final HttpClientConnection conn = getConnection(mgr, route); mgr.connect(conn, route, 0, context); mgr.routeComplete(conn, route, context); Assert.assertEquals(1, mgr.getTotalStats().getLeased()); Assert.assertEquals(1, mgr.getStats(route).getLeased()); // Release, let remain idle for forever mgr.releaseConnection(conn, null, -1, TimeUnit.MILLISECONDS); // Released, still active. Assert.assertEquals(1, mgr.getTotalStats().getAvailable()); Assert.assertEquals(1, mgr.getStats(route).getAvailable()); mgr.closeExpiredConnections(); // Time has not expired yet. Assert.assertEquals(1, mgr.getTotalStats().getAvailable()); Assert.assertEquals(1, mgr.getStats(route).getAvailable()); Thread.sleep(150); mgr.closeExpiredConnections(); // TTL expired now, connections are destroyed. Assert.assertEquals(0, mgr.getTotalStats().getAvailable()); Assert.assertEquals(0, mgr.getStats(route).getAvailable()); mgr.shutdown(); } /** * Tests releasing connection from #abort method called from the * main execution thread while there is no blocking I/O operation. */ @Test public void testReleaseConnectionOnAbort() throws Exception { final PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager(); mgr.setMaxTotal(1); final HttpHost target = getServerHttp(); final HttpRoute route = new HttpRoute(target, null, false); final int rsplen = 8; final String uri = "/random/" + rsplen; final HttpContext context = new BasicHttpContext(); final HttpRequest request = new BasicHttpRequest("GET", uri, HttpVersion.HTTP_1_1); HttpClientConnection conn = getConnection(mgr, route); mgr.connect(conn, route, 0, context); mgr.routeComplete(conn, route, context); context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, target); final HttpProcessor httpProcessor = new ImmutableHttpProcessor( new HttpRequestInterceptor[] { new RequestContent(), new RequestConnControl() }); final HttpRequestExecutor exec = new HttpRequestExecutor(); exec.preProcess(request, httpProcessor, context); final HttpResponse response = exec.execute(request, conn, context); Assert.assertEquals("wrong status in first response", HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); // check that there are no connections available try { // this should fail quickly, connection has not been released getConnection(mgr, route, 100L, TimeUnit.MILLISECONDS); Assert.fail("ConnectionPoolTimeoutException should have been thrown"); } catch (final ConnectionPoolTimeoutException e) { // expected } // abort the connection Assert.assertTrue(conn instanceof HttpClientConnection); conn.shutdown(); mgr.releaseConnection(conn, null, -1, null); // the connection is expected to be released back to the manager conn = getConnection(mgr, route, 5L, TimeUnit.SECONDS); Assert.assertFalse("connection should have been closed", conn.isOpen()); mgr.releaseConnection(conn, null, -1, null); mgr.shutdown(); } @Test public void testAbortDuringConnecting() throws Exception { final CountDownLatch connectLatch = new CountDownLatch(1); final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory( connectLatch, WaitPolicy.BEFORE_CONNECT, PlainConnectionSocketFactory.getSocketFactory()); final Registry registry = RegistryBuilder.create() .register("http", stallingSocketFactory) .build(); final PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager(registry); mgr.setMaxTotal(1); final HttpHost target = getServerHttp(); final HttpRoute route = new HttpRoute(target, null, false); final HttpContext context = new BasicHttpContext(); final HttpClientConnection conn = getConnection(mgr, route); final AtomicReference throwRef = new AtomicReference(); final Thread abortingThread = new Thread(new Runnable() { public void run() { try { stallingSocketFactory.waitForState(); conn.shutdown(); mgr.releaseConnection(conn, null, -1, null); connectLatch.countDown(); } catch (final Throwable e) { throwRef.set(e); } } }); abortingThread.start(); try { mgr.connect(conn, route, 0, context); mgr.routeComplete(conn, route, context); Assert.fail("expected SocketException"); } catch(final SocketException expected) {} abortingThread.join(5000); if(throwRef.get() != null) { throw new RuntimeException(throwRef.get()); } Assert.assertFalse(conn.isOpen()); Assert.assertEquals(0, localServer.getAcceptedConnectionCount()); // the connection is expected to be released back to the manager final HttpClientConnection conn2 = getConnection(mgr, route, 5L, TimeUnit.SECONDS); Assert.assertFalse("connection should have been closed", conn2.isOpen()); mgr.releaseConnection(conn2, null, -1, null); mgr.shutdown(); } @Test public void testAbortBeforeSocketCreate() throws Exception { final CountDownLatch connectLatch = new CountDownLatch(1); final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory( connectLatch, WaitPolicy.BEFORE_CREATE, PlainConnectionSocketFactory.getSocketFactory()); final Registry registry = RegistryBuilder.create() .register("http", stallingSocketFactory) .build(); final PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager(registry); mgr.setMaxTotal(1); final HttpHost target = getServerHttp(); final HttpRoute route = new HttpRoute(target, null, false); final HttpContext context = new BasicHttpContext(); final HttpClientConnection conn = getConnection(mgr, route); final AtomicReference throwRef = new AtomicReference(); final Thread abortingThread = new Thread(new Runnable() { public void run() { try { stallingSocketFactory.waitForState(); conn.shutdown(); mgr.releaseConnection(conn, null, -1, null); connectLatch.countDown(); } catch (final Throwable e) { throwRef.set(e); } } }); abortingThread.start(); try { mgr.connect(conn, route, 0, context); mgr.routeComplete(conn, route, context); Assert.fail("IOException expected"); } catch(final IOException expected) { } abortingThread.join(5000); if(throwRef.get() != null) { throw new RuntimeException(throwRef.get()); } Assert.assertFalse(conn.isOpen()); Assert.assertEquals(0, localServer.getAcceptedConnectionCount()); // the connection is expected to be released back to the manager final HttpClientConnection conn2 = getConnection(mgr, route, 5L, TimeUnit.SECONDS); Assert.assertFalse("connection should have been closed", conn2.isOpen()); mgr.releaseConnection(conn2, null, -1, null); mgr.shutdown(); } @Test public void testAbortAfterSocketConnect() throws Exception { final CountDownLatch connectLatch = new CountDownLatch(1); final StallingSocketFactory stallingSocketFactory = new StallingSocketFactory( connectLatch, WaitPolicy.AFTER_CONNECT, PlainConnectionSocketFactory.getSocketFactory()); final Registry registry = RegistryBuilder.create() .register("http", stallingSocketFactory) .build(); final PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager(registry); mgr.setMaxTotal(1); final HttpHost target = getServerHttp(); final HttpRoute route = new HttpRoute(target, null, false); final HttpContext context = new BasicHttpContext(); final HttpClientConnection conn = getConnection(mgr, route); final AtomicReference throwRef = new AtomicReference(); final Thread abortingThread = new Thread(new Runnable() { public void run() { try { stallingSocketFactory.waitForState(); conn.shutdown(); mgr.releaseConnection(conn, null, -1, null); connectLatch.countDown(); } catch (final Throwable e) { throwRef.set(e); } } }); abortingThread.start(); try { mgr.connect(conn, route, 0, context); mgr.routeComplete(conn, route, context); Assert.fail("IOException expected"); } catch(final IOException expected) { } abortingThread.join(5000); if(throwRef.get() != null) { throw new RuntimeException(throwRef.get()); } Assert.assertFalse(conn.isOpen()); // Give the server a bit of time to accept the connection, but // ensure that it can accept it. for(int i = 0; i < 10; i++) { if(localServer.getAcceptedConnectionCount() == 1) { break; } Thread.sleep(100); } Assert.assertEquals(1, localServer.getAcceptedConnectionCount()); // the connection is expected to be released back to the manager final HttpClientConnection conn2 = getConnection(mgr, route, 5L, TimeUnit.SECONDS); Assert.assertFalse("connection should have been closed", conn2.isOpen()); mgr.releaseConnection(conn2, null, -1, null); mgr.shutdown(); } static class LatchSupport { private final CountDownLatch continueLatch; private final CountDownLatch waitLatch = new CountDownLatch(1); protected final WaitPolicy waitPolicy; LatchSupport(final CountDownLatch continueLatch, final WaitPolicy waitPolicy) { this.continueLatch = continueLatch; this.waitPolicy = waitPolicy; } void waitForState() throws InterruptedException { if(!waitLatch.await(1, TimeUnit.SECONDS)) { throw new RuntimeException("waited too long"); } } void latch() { waitLatch.countDown(); try { if (!continueLatch.await(60, TimeUnit.SECONDS)) { throw new RuntimeException("waited too long!"); } } catch (final InterruptedException e) { throw new RuntimeException(e); } } } private static class StallingSocketFactory extends LatchSupport implements ConnectionSocketFactory { private final ConnectionSocketFactory delegate; public StallingSocketFactory( final CountDownLatch continueLatch, final WaitPolicy waitPolicy, final ConnectionSocketFactory delegate) { super(continueLatch, waitPolicy); this.delegate = delegate; } public Socket connectSocket( final int connectTimeout, final Socket sock, final HttpHost host, final InetSocketAddress remoteAddress, final InetSocketAddress localAddress, final HttpContext context) throws IOException, ConnectTimeoutException { if(waitPolicy == WaitPolicy.BEFORE_CONNECT) { latch(); } final Socket socket = delegate.connectSocket( connectTimeout, sock, host, remoteAddress, localAddress, context); if(waitPolicy == WaitPolicy.AFTER_CONNECT) { latch(); } return socket; } public Socket createSocket(final HttpContext context) throws IOException { if(waitPolicy == WaitPolicy.BEFORE_CREATE) { latch(); } return delegate.createSocket(context); } } private enum WaitPolicy { BEFORE_CREATE, BEFORE_CONNECT, AFTER_CONNECT, AFTER_OPEN } } ././@LongLink0100644 0000000 0000000 00000000166 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestConnectionReuse.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCon0100644 0000000 0000000 00000030157 12301751657 032526 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.IOException; import java.net.InetSocketAddress; import java.net.URI; import org.apache.http.Header; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseInterceptor; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.localserver.LocalTestServer; import org.apache.http.localserver.RandomHandler; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpProcessorBuilder; import org.apache.http.protocol.ResponseConnControl; import org.apache.http.protocol.ResponseContent; import org.apache.http.protocol.ResponseDate; import org.apache.http.protocol.ResponseServer; import org.apache.http.util.EntityUtils; import org.junit.After; import org.junit.Assert; import org.junit.Test; public class TestConnectionReuse { protected LocalTestServer localServer; @After public void tearDown() throws Exception { if (this.localServer != null) { this.localServer.stop(); } } @Test public void testReuseOfPersistentConnections() throws Exception { final HttpProcessor httpproc = HttpProcessorBuilder.create() .add(new ResponseDate()) .add(new ResponseServer()) .add(new ResponseContent()) .add(new ResponseConnControl()).build(); this.localServer = new LocalTestServer(httpproc, null); this.localServer.register("/random/*", new RandomHandler()); this.localServer.start(); final InetSocketAddress saddress = this.localServer.getServiceAddress(); final PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager(); mgr.setMaxTotal(5); mgr.setDefaultMaxPerRoute(5); final HttpClient client = HttpClients.custom().setConnectionManager(mgr).build(); final HttpHost target = new HttpHost(saddress.getHostName(), saddress.getPort(), "http"); final WorkerThread[] workers = new WorkerThread[10]; for (int i = 0; i < workers.length; i++) { workers[i] = new WorkerThread( client, target, new URI("/random/2000"), 10, false); } for (final WorkerThread worker : workers) { worker.start(); } for (final WorkerThread worker : workers) { worker.join(10000); final Exception ex = worker.getException(); if (ex != null) { throw ex; } } // Expect some connection in the pool Assert.assertTrue(mgr.getTotalStats().getAvailable() > 0); mgr.shutdown(); } private static class AlwaysCloseConn implements HttpResponseInterceptor { public void process( final HttpResponse response, final HttpContext context) throws HttpException, IOException { response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); } } @Test public void testReuseOfClosedConnections() throws Exception { final HttpProcessor httpproc = HttpProcessorBuilder.create() .add(new ResponseDate()) .add(new ResponseServer()) .add(new ResponseContent()) .add(new AlwaysCloseConn()).build(); this.localServer = new LocalTestServer(httpproc, null); this.localServer.register("/random/*", new RandomHandler()); this.localServer.start(); final InetSocketAddress saddress = this.localServer.getServiceAddress(); final PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager(); mgr.setMaxTotal(5); mgr.setDefaultMaxPerRoute(5); final HttpClient client = HttpClients.custom().setConnectionManager(mgr).build(); final HttpHost target = new HttpHost(saddress.getHostName(), saddress.getPort(), "http"); final WorkerThread[] workers = new WorkerThread[10]; for (int i = 0; i < workers.length; i++) { workers[i] = new WorkerThread( client, target, new URI("/random/2000"), 10, false); } for (final WorkerThread worker : workers) { worker.start(); } for (final WorkerThread worker : workers) { worker.join(10000); final Exception ex = worker.getException(); if (ex != null) { throw ex; } } // Expect zero connections in the pool Assert.assertEquals(0, mgr.getTotalStats().getAvailable()); mgr.shutdown(); } @Test public void testReuseOfAbortedConnections() throws Exception { final HttpProcessor httpproc = HttpProcessorBuilder.create() .add(new ResponseDate()) .add(new ResponseServer()) .add(new ResponseContent()) .add(new ResponseConnControl()).build(); this.localServer = new LocalTestServer(httpproc, null); this.localServer.register("/random/*", new RandomHandler()); this.localServer.start(); final InetSocketAddress saddress = this.localServer.getServiceAddress(); final PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager(); mgr.setMaxTotal(5); mgr.setDefaultMaxPerRoute(5); final HttpClient client = HttpClients.custom().setConnectionManager(mgr).build(); final HttpHost target = new HttpHost(saddress.getHostName(), saddress.getPort(), "http"); final WorkerThread[] workers = new WorkerThread[10]; for (int i = 0; i < workers.length; i++) { workers[i] = new WorkerThread( client, target, new URI("/random/2000"), 10, true); } for (final WorkerThread worker : workers) { worker.start(); } for (final WorkerThread worker : workers) { worker.join(10000); final Exception ex = worker.getException(); if (ex != null) { throw ex; } } // Expect zero connections in the pool Assert.assertEquals(0, mgr.getTotalStats().getAvailable()); mgr.shutdown(); } @Test public void testKeepAliveHeaderRespected() throws Exception { final HttpProcessor httpproc = HttpProcessorBuilder.create() .add(new ResponseDate()) .add(new ResponseServer()) .add(new ResponseContent()) .add(new ResponseConnControl()) .add(new ResponseKeepAlive()).build(); this.localServer = new LocalTestServer(httpproc, null); this.localServer.register("/random/*", new RandomHandler()); this.localServer.start(); final InetSocketAddress saddress = this.localServer.getServiceAddress(); final PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager(); mgr.setMaxTotal(1); mgr.setDefaultMaxPerRoute(1); final HttpClient client = HttpClients.custom().setConnectionManager(mgr).build(); final HttpHost target = new HttpHost(saddress.getHostName(), saddress.getPort(), "http"); HttpResponse response = client.execute(target, new HttpGet("/random/2000")); EntityUtils.consume(response.getEntity()); Assert.assertEquals(1, mgr.getTotalStats().getAvailable()); Assert.assertEquals(1, localServer.getAcceptedConnectionCount()); response = client.execute(target, new HttpGet("/random/2000")); EntityUtils.consume(response.getEntity()); Assert.assertEquals(1, mgr.getTotalStats().getAvailable()); Assert.assertEquals(1, localServer.getAcceptedConnectionCount()); // Now sleep for 1.1 seconds and let the timeout do its work Thread.sleep(1100); response = client.execute(target, new HttpGet("/random/2000")); EntityUtils.consume(response.getEntity()); Assert.assertEquals(1, mgr.getTotalStats().getAvailable()); Assert.assertEquals(2, localServer.getAcceptedConnectionCount()); // Do another request just under the 1 second limit & make // sure we reuse that connection. Thread.sleep(500); response = client.execute(target, new HttpGet("/random/2000")); EntityUtils.consume(response.getEntity()); Assert.assertEquals(1, mgr.getTotalStats().getAvailable()); Assert.assertEquals(2, localServer.getAcceptedConnectionCount()); mgr.shutdown(); } private static class WorkerThread extends Thread { private final URI requestURI; private final HttpHost target; private final HttpClient httpclient; private final int repetitions; private final boolean forceClose; private volatile Exception exception; public WorkerThread( final HttpClient httpclient, final HttpHost target, final URI requestURI, final int repetitions, final boolean forceClose) { super(); this.httpclient = httpclient; this.requestURI = requestURI; this.target = target; this.repetitions = repetitions; this.forceClose = forceClose; } @Override public void run() { try { for (int i = 0; i < this.repetitions; i++) { final HttpGet httpget = new HttpGet(this.requestURI); final HttpResponse response = this.httpclient.execute( this.target, httpget); if (this.forceClose) { httpget.abort(); } else { EntityUtils.consume(response.getEntity()); } } } catch (final Exception ex) { this.exception = ex; } } public Exception getException() { return exception; } } // A very basic keep-alive header interceptor, to add Keep-Alive: timeout=1 // if there is no Connection: close header. private static class ResponseKeepAlive implements HttpResponseInterceptor { public void process(final HttpResponse response, final HttpContext context) throws HttpException, IOException { final Header connection = response.getFirstHeader(HTTP.CONN_DIRECTIVE); if(connection != null) { if(!connection.getValue().equalsIgnoreCase("Close")) { response.addHeader(HTTP.CONN_KEEP_ALIVE, "timeout=1"); } } } } } ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestContentCodings.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCon0100644 0000000 0000000 00000043743 12301751657 032533 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.zip.Deflater; import java.util.zip.GZIPOutputStream; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * Test case for how Content Codings are processed. By default, we want to do the right thing and * require no intervention from the user of HttpClient, but we still want to let clients do their * own thing if they so wish. */ public class TestContentCodings extends IntegrationTestBase { @Before public void setUp() throws Exception { startServer(); } /** * Test for when we don't get an entity back; e.g. for a 204 or 304 response; nothing blows * up with the new behaviour. * * @throws Exception * if there was a problem */ @Test public void testResponseWithNoContent() throws Exception { this.localServer.register("*", new HttpRequestHandler() { /** * {@inheritDoc} */ public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { response.setStatusCode(HttpStatus.SC_NO_CONTENT); } }); this.httpclient = HttpClients.custom().build(); final HttpGet request = new HttpGet("/some-resource"); final HttpResponse response = this.httpclient.execute(getServerHttp(), request); Assert.assertEquals(HttpStatus.SC_NO_CONTENT, response.getStatusLine().getStatusCode()); Assert.assertNull(response.getEntity()); } /** * Test for when we are handling content from a server that has correctly interpreted RFC2616 * to return RFC1950 streams for deflate content coding. * * @throws Exception */ @Test public void testDeflateSupportForServerReturningRfc1950Stream() throws Exception { final String entityText = "Hello, this is some plain text coming back."; this.localServer.register("*", createDeflateEncodingRequestHandler(entityText, false)); this.httpclient = HttpClients.custom().build(); final HttpGet request = new HttpGet("/some-resource"); final HttpResponse response = this.httpclient.execute(getServerHttp(), request); Assert.assertEquals("The entity text is correctly transported", entityText, EntityUtils.toString(response.getEntity())); } /** * Test for when we are handling content from a server that has incorrectly interpreted RFC2616 * to return RFC1951 streams for deflate content coding. * * @throws Exception */ @Test public void testDeflateSupportForServerReturningRfc1951Stream() throws Exception { final String entityText = "Hello, this is some plain text coming back."; this.localServer.register("*", createDeflateEncodingRequestHandler(entityText, true)); this.httpclient = HttpClients.custom().build(); final HttpGet request = new HttpGet("/some-resource"); final HttpResponse response = this.httpclient.execute(getServerHttp(), request); Assert.assertEquals("The entity text is correctly transported", entityText, EntityUtils.toString(response.getEntity())); } /** * Test for a server returning gzipped content. * * @throws Exception */ @Test public void testGzipSupport() throws Exception { final String entityText = "Hello, this is some plain text coming back."; this.localServer.register("*", createGzipEncodingRequestHandler(entityText)); this.httpclient = HttpClients.custom().build(); final HttpGet request = new HttpGet("/some-resource"); final HttpResponse response = this.httpclient.execute(getServerHttp(), request); Assert.assertEquals("The entity text is correctly transported", entityText, EntityUtils.toString(response.getEntity())); } /** * Try with a bunch of client threads, to check that it's thread-safe. * * @throws Exception * if there was a problem */ @Test public void testThreadSafetyOfContentCodings() throws Exception { final String entityText = "Hello, this is some plain text coming back."; this.localServer.register("*", createGzipEncodingRequestHandler(entityText)); /* * Create a load of workers which will access the resource. Half will use the default * gzip behaviour; half will require identity entity. */ final int clients = 100; final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); cm.setMaxTotal(clients); this.httpclient = HttpClients.custom().setConnectionManager(cm).build(); final ExecutorService executor = Executors.newFixedThreadPool(clients); final CountDownLatch startGate = new CountDownLatch(1); final CountDownLatch endGate = new CountDownLatch(clients); final List workers = new ArrayList(); for (int i = 0; i < clients; ++i) { workers.add(new WorkerTask(this.httpclient, i % 2 == 0, startGate, endGate)); } for (final WorkerTask workerTask : workers) { /* Set them all in motion, but they will block until we call startGate.countDown(). */ executor.execute(workerTask); } startGate.countDown(); /* Wait for the workers to complete. */ endGate.await(); for (final WorkerTask workerTask : workers) { if (workerTask.isFailed()) { Assert.fail("A worker failed"); } Assert.assertEquals(entityText, workerTask.getText()); } } @Test public void testHttpEntityWriteToForGzip() throws Exception { final String entityText = "Hello, this is some plain text coming back."; this.localServer.register("*", createGzipEncodingRequestHandler(entityText)); this.httpclient = HttpClients.custom().build(); final HttpGet request = new HttpGet("/some-resource"); final HttpResponse response = this.httpclient.execute(getServerHttp(), request); final ByteArrayOutputStream out = new ByteArrayOutputStream(); response.getEntity().writeTo(out); Assert.assertEquals(entityText, out.toString("utf-8")); } @Test public void testHttpEntityWriteToForDeflate() throws Exception { final String entityText = "Hello, this is some plain text coming back."; this.localServer.register("*", createDeflateEncodingRequestHandler(entityText, true)); this.httpclient = HttpClients.custom().build(); final HttpGet request = new HttpGet("/some-resource"); final HttpResponse response = this.httpclient.execute(getServerHttp(), request); final ByteArrayOutputStream out = new ByteArrayOutputStream(); response.getEntity().writeTo(out); Assert.assertEquals(entityText, out.toString("utf-8")); } @Test public void gzipResponsesWorkWithBasicResponseHandler() throws Exception { final String entityText = "Hello, this is some plain text coming back."; this.localServer.register("*", createGzipEncodingRequestHandler(entityText)); this.httpclient = HttpClients.custom().build(); final HttpGet request = new HttpGet("/some-resource"); final String response = this.httpclient.execute(getServerHttp(), request, new BasicResponseHandler()); Assert.assertEquals("The entity text is correctly transported", entityText, response); } @Test public void deflateResponsesWorkWithBasicResponseHandler() throws Exception { final String entityText = "Hello, this is some plain text coming back."; this.localServer.register("*", createDeflateEncodingRequestHandler(entityText, false)); this.httpclient = HttpClients.custom().build(); final HttpGet request = new HttpGet("/some-resource"); final String response = this.httpclient.execute(getServerHttp(), request, new BasicResponseHandler()); Assert.assertEquals("The entity text is correctly transported", entityText, response); } /** * Creates a new {@link HttpRequestHandler} that will attempt to provide a deflate stream * Content-Coding. * * @param entityText * the non-null String entity text to be returned by the server * @param rfc1951 * if true, then the stream returned will be a raw RFC1951 deflate stream, which * some servers return as a result of misinterpreting the HTTP 1.1 RFC. If false, * then it will return an RFC2616 compliant deflate encoded zlib stream. * @return a non-null {@link HttpRequestHandler} */ private HttpRequestHandler createDeflateEncodingRequestHandler( final String entityText, final boolean rfc1951) { return new HttpRequestHandler() { /** * {@inheritDoc} */ public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { response.setEntity(new StringEntity(entityText)); response.addHeader("Content-Type", "text/plain"); final Header[] acceptEncodings = request.getHeaders("Accept-Encoding"); for (final Header header : acceptEncodings) { for (final HeaderElement element : header.getElements()) { if ("deflate".equalsIgnoreCase(element.getName())) { response.addHeader("Content-Encoding", "deflate"); /* Gack. DeflaterInputStream is Java 6. */ // response.setEntity(new InputStreamEntity(new DeflaterInputStream(new // ByteArrayInputStream( // entityText.getBytes("utf-8"))), -1)); final byte[] uncompressed = entityText.getBytes("utf-8"); final Deflater compressor = new Deflater(Deflater.DEFAULT_COMPRESSION, rfc1951); compressor.setInput(uncompressed); compressor.finish(); final byte[] output = new byte[100]; final int compressedLength = compressor.deflate(output); final byte[] compressed = new byte[compressedLength]; System.arraycopy(output, 0, compressed, 0, compressedLength); response.setEntity(new InputStreamEntity( new ByteArrayInputStream(compressed), compressedLength)); return; } } } } }; } /** * Returns an {@link HttpRequestHandler} implementation that will attempt to provide a gzip * Content-Encoding. * * @param entityText * the non-null String entity to be returned by the server * @return a non-null {@link HttpRequestHandler} */ private HttpRequestHandler createGzipEncodingRequestHandler(final String entityText) { return new HttpRequestHandler() { /** * {@inheritDoc} */ public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { response.setEntity(new StringEntity(entityText)); response.addHeader("Content-Type", "text/plain"); final Header[] acceptEncodings = request.getHeaders("Accept-Encoding"); for (final Header header : acceptEncodings) { for (final HeaderElement element : header.getElements()) { if ("gzip".equalsIgnoreCase(element.getName())) { response.addHeader("Content-Encoding", "gzip"); /* * We have to do a bit more work with gzip versus deflate, since * Gzip doesn't appear to have an equivalent to DeflaterInputStream in * the JDK. * * UPDATE: DeflaterInputStream is Java 6 anyway, so we have to do a bit * of work there too! */ final ByteArrayOutputStream bytes = new ByteArrayOutputStream(); final OutputStream out = new GZIPOutputStream(bytes); final ByteArrayInputStream uncompressed = new ByteArrayInputStream( entityText.getBytes("utf-8")); final byte[] buf = new byte[60]; int n; while ((n = uncompressed.read(buf)) != -1) { out.write(buf, 0, n); } out.close(); final byte[] arr = bytes.toByteArray(); response.setEntity(new InputStreamEntity(new ByteArrayInputStream(arr), arr.length)); return; } } } } }; } /** * Sub-ordinate task passed off to a different thread to be executed. * * @author jabley * */ class WorkerTask implements Runnable { /** * The {@link HttpClient} used to make requests. */ private final HttpClient client; /** * The {@link HttpRequest} to be executed. */ private final HttpGet request; /** * Flag indicating if there were failures. */ private boolean failed = false; /** * The latch that this runnable instance should wait on. */ private final CountDownLatch startGate; /** * The latch that this runnable instance should countdown on when the runnable is finished. */ private final CountDownLatch endGate; /** * The text returned from the HTTP server. */ private String text; WorkerTask(final HttpClient client, final boolean identity, final CountDownLatch startGate, final CountDownLatch endGate) { this.client = client; this.request = new HttpGet("/some-resource"); if (identity) { request.addHeader("Accept-Encoding", "identity"); } this.startGate = startGate; this.endGate = endGate; } /** * Returns the text of the HTTP entity. * * @return a String - may be null. */ public String getText() { return this.text; } /** * {@inheritDoc} */ public void run() { try { startGate.await(); try { final HttpResponse response = client.execute(TestContentCodings.this.getServerHttp(), request); text = EntityUtils.toString(response.getEntity()); } catch (final Exception e) { failed = true; } finally { endGate.countDown(); } } catch (final InterruptedException ignore) { } } /** * Returns true if this task failed, otherwise false. * * @return a flag */ boolean isFailed() { return this.failed; } } } ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCookie2Support.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCoo0100644 0000000 0000000 00000022650 12301751657 032526 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.IOException; import java.util.List; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.ProtocolVersion; import org.apache.http.client.CookieStore; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.SM; import org.apache.http.cookie.SetCookie2; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * Cookie2 support tests. */ public class TestCookie2Support extends IntegrationTestBase { @Before public void setUp() throws Exception { startServer(); this.httpclient = HttpClients.createDefault(); } private static class CookieVer0Service implements HttpRequestHandler { public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final ProtocolVersion httpversion = request.getRequestLine().getProtocolVersion(); response.setStatusLine(httpversion, HttpStatus.SC_OK); response.addHeader(new BasicHeader("Set-Cookie", "name1=value1; path=/test")); final StringEntity entity = new StringEntity("whatever"); response.setEntity(entity); } } @Test public void testCookieVersionSupportHeader1() throws Exception { this.localServer.register("*", new CookieVer0Service()); final CookieStore cookieStore = new BasicCookieStore(); final HttpClientContext context = HttpClientContext.create(); context.setCookieStore(cookieStore); final HttpGet httpget = new HttpGet("/test/"); final HttpResponse response1 = this.httpclient.execute(getServerHttp(), httpget, context); final HttpEntity e1 = response1.getEntity(); EntityUtils.consume(e1); final List cookies = cookieStore.getCookies(); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final HttpResponse response2 = this.httpclient.execute(getServerHttp(), httpget, context); final HttpEntity e2 = response2.getEntity(); EntityUtils.consume(e2); final HttpRequest reqWrapper = context.getRequest(); final Header cookiesupport = reqWrapper.getFirstHeader("Cookie2"); Assert.assertNotNull(cookiesupport); Assert.assertEquals("$Version=1", cookiesupport.getValue()); } private static class CookieVer1Service implements HttpRequestHandler { public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final ProtocolVersion httpversion = request.getRequestLine().getProtocolVersion(); response.setStatusLine(httpversion, HttpStatus.SC_OK); response.addHeader(new BasicHeader("Set-Cookie", "name1=value1; Path=\"/test\"; Version=1")); response.addHeader(new BasicHeader("Set-Cookie2", "name2=value2; Path=\"/test\"; Version=1")); final StringEntity entity = new StringEntity("whatever"); response.setEntity(entity); } } @Test public void testCookieVersionSupportHeader2() throws Exception { this.localServer.register("*", new CookieVer1Service()); final CookieStore cookieStore = new BasicCookieStore(); final HttpClientContext context = HttpClientContext.create(); context.setCookieStore(cookieStore); final HttpGet httpget = new HttpGet("/test/"); final HttpResponse response1 = this.httpclient.execute(getServerHttp(), httpget, context); final HttpEntity e1 = response1.getEntity(); EntityUtils.consume(e1); final List cookies = cookieStore.getCookies(); Assert.assertNotNull(cookies); Assert.assertEquals(2, cookies.size()); final HttpResponse response2 = this.httpclient.execute(getServerHttp(), httpget, context); final HttpEntity e2 = response2.getEntity(); EntityUtils.consume(e2); final HttpRequest reqWrapper = context.getRequest(); final Header cookiesupport = reqWrapper.getFirstHeader(SM.COOKIE2); Assert.assertNotNull(cookiesupport); Assert.assertEquals("$Version=1", cookiesupport.getValue()); } private static class CookieVer2Service implements HttpRequestHandler { public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final ProtocolVersion httpversion = request.getRequestLine().getProtocolVersion(); response.setStatusLine(httpversion, HttpStatus.SC_OK); response.addHeader(new BasicHeader("Set-Cookie2", "name2=value2; Path=\"/test\"; Version=2")); final StringEntity entity = new StringEntity("whatever"); response.setEntity(entity); } } @Test public void testCookieVersionSupportHeader3() throws Exception { this.localServer.register("*", new CookieVer2Service()); final CookieStore cookieStore = new BasicCookieStore(); final HttpClientContext context = HttpClientContext.create(); context.setCookieStore(cookieStore); final HttpGet httpget = new HttpGet("/test/"); final HttpResponse response1 = this.httpclient.execute(getServerHttp(), httpget, context); final HttpEntity e1 = response1.getEntity(); EntityUtils.consume(e1); final List cookies = cookieStore.getCookies(); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final HttpResponse response2 = this.httpclient.execute(getServerHttp(), httpget, context); final HttpEntity e2 = response2.getEntity(); EntityUtils.consume(e2); final HttpRequest reqWrapper = context.getRequest(); final Header cookiesupport = reqWrapper.getFirstHeader("Cookie2"); Assert.assertNotNull(cookiesupport); Assert.assertEquals("$Version=1", cookiesupport.getValue()); } private static class SetCookieVersionMixService implements HttpRequestHandler { public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final ProtocolVersion httpversion = request.getRequestLine().getProtocolVersion(); response.setStatusLine(httpversion, HttpStatus.SC_OK); response.addHeader(new BasicHeader("Set-Cookie", "name=wrong; Path=/test")); response.addHeader(new BasicHeader("Set-Cookie2", "name=right; Path=\"/test\"; Version=1")); final StringEntity entity = new StringEntity("whatever"); response.setEntity(entity); } } @Test public void testSetCookieVersionMix() throws Exception { this.localServer.register("*", new SetCookieVersionMixService()); final CookieStore cookieStore = new BasicCookieStore(); final HttpClientContext context = HttpClientContext.create(); context.setCookieStore(cookieStore); final HttpGet httpget = new HttpGet("/test/"); final HttpResponse response1 = this.httpclient.execute(getServerHttp(), httpget, context); final HttpEntity e1 = response1.getEntity(); EntityUtils.consume(e1); final List cookies = cookieStore.getCookies(); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); Assert.assertEquals("right", cookies.get(0).getValue()); Assert.assertTrue(cookies.get(0) instanceof SetCookie2); } } ././@LongLink0100644 0000000 0000000 00000000170 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCookieVirtualHost.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestCoo0100644 0000000 0000000 00000014124 12301751657 032523 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.IOException; import java.net.URI; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.client.CookieStore; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.HttpClients; import org.apache.http.localserver.LocalTestServer; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * This class tests cookie matching when using Virtual Host. */ public class TestCookieVirtualHost extends IntegrationTestBase { @Before public void setUp() throws Exception { this.localServer = new LocalTestServer(null, null); this.localServer.registerDefaultHandlers(); this.localServer.start(); } @Test public void testCookieMatchingWithVirtualHosts() throws Exception { this.localServer.register("*", new HttpRequestHandler() { public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final int n = Integer.parseInt(request.getFirstHeader("X-Request").getValue()); switch (n) { case 1: // Assert Host is forwarded from URI Assert.assertEquals("app.mydomain.fr", request .getFirstHeader("Host").getValue()); response.setStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); // Respond with Set-Cookie on virtual host domain. This // should be valid. response.addHeader(new BasicHeader("Set-Cookie", "name1=value1; domain=mydomain.fr; path=/")); break; case 2: // Assert Host is still forwarded from URI Assert.assertEquals("app.mydomain.fr", request .getFirstHeader("Host").getValue()); // We should get our cookie back. Assert.assertNotNull("We must get a cookie header", request.getFirstHeader("Cookie")); response.setStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); break; case 3: // Assert Host is forwarded from URI Assert.assertEquals("app.mydomain.fr", request .getFirstHeader("Host").getValue()); response.setStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK); break; } } }); this.httpclient = HttpClients.createDefault(); final CookieStore cookieStore = new BasicCookieStore(); final HttpClientContext context = HttpClientContext.create(); context.setCookieStore(cookieStore); // First request : retrieve a domain cookie from remote server. URI uri = new URI("http://app.mydomain.fr"); HttpRequest httpRequest = new HttpGet(uri); httpRequest.addHeader("X-Request", "1"); final HttpResponse response1 = this.httpclient.execute(getServerHttp(), httpRequest, context); final HttpEntity e1 = response1.getEntity(); EntityUtils.consume(e1); // We should have one cookie set on domain. final List cookies = cookieStore.getCookies(); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); Assert.assertEquals("name1", cookies.get(0).getName()); // Second request : send the cookie back. uri = new URI("http://app.mydomain.fr"); httpRequest = new HttpGet(uri); httpRequest.addHeader("X-Request", "2"); final HttpResponse response2 = this.httpclient.execute(getServerHttp(), httpRequest, context); final HttpEntity e2 = response2.getEntity(); EntityUtils.consume(e2); // Third request : Host header uri = new URI("http://app.mydomain.fr"); httpRequest = new HttpGet(uri); httpRequest.addHeader("X-Request", "3"); final HttpResponse response3 = this.httpclient.execute(getServerHttp(), httpRequest, context); final HttpEntity e3 = response3.getEntity(); EntityUtils.consume(e3); } } ././@LongLink0100644 0000000 0000000 00000000175 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestIdleConnectionEviction.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestIdl0100644 0000000 0000000 00000013461 12301751657 032516 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.localserver.LocalServerTestBase; import org.apache.http.localserver.LocalTestServer; import org.apache.http.util.EntityUtils; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; public class TestIdleConnectionEviction extends LocalServerTestBase { @Before public void setUp() throws Exception { this.localServer = new LocalTestServer(null, null); this.localServer.registerDefaultHandlers(); this.localServer.start(); } @Test @Ignore("We have a concurrency bug in HttpCore which will be addressed after HttpClient 4.3.2 is released") public void testIdleConnectionEviction() throws Exception { final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); cm.setDefaultMaxPerRoute(10); cm.setMaxTotal(50); final HttpClient httpclient = HttpClients.custom().setConnectionManager(cm).build(); final IdleConnectionMonitor idleConnectionMonitor = new IdleConnectionMonitor(cm); idleConnectionMonitor.start(); final InetSocketAddress address = this.localServer.getServiceAddress(); final HttpHost target = new HttpHost(address.getHostName(), address.getPort()); final HttpGet httpget = new HttpGet("/random/1024"); final WorkerThread[] workers = new WorkerThread[5]; for (int i = 0; i < workers.length; i++) { workers[i] = new WorkerThread(httpclient, target, httpget, 200); } for (final WorkerThread worker : workers) { worker.start(); } for (final WorkerThread worker : workers) { worker.join(); final Exception ex = worker.getException(); if (ex != null) { throw ex; } } idleConnectionMonitor.shutdown(); } static class WorkerThread extends Thread { private final HttpClient httpclient; private final HttpHost target; private final HttpUriRequest request; private final int count; private volatile Exception ex; public WorkerThread( final HttpClient httpclient, final HttpHost target, final HttpUriRequest request, final int count) { super(); this.httpclient = httpclient; this.target = target; this.request = request; this.count = count; } @Override public void run() { try { for (int i = 0; i < this.count; i++) { final HttpResponse response = this.httpclient.execute(this.target, this.request); final int status = response.getStatusLine().getStatusCode(); if (status != 200) { this.request.abort(); throw new ClientProtocolException("Unexpected status code: " + status); } EntityUtils.consume(response.getEntity()); Thread.sleep(10); } } catch (final Exception ex) { this.ex = ex; } } public Exception getException() { return ex; } } public static class IdleConnectionMonitor extends Thread { private final HttpClientConnectionManager cm; private volatile boolean shutdown; public IdleConnectionMonitor(final HttpClientConnectionManager cm) { super(); this.cm = cm; setDaemon(true); } @Override public void run() { try { while (!this.shutdown) { synchronized (this) { wait(250); this.cm.closeIdleConnections(1, TimeUnit.MILLISECONDS); } } } catch (final InterruptedException ex) { // terminate } } public void shutdown() { this.shutdown = true; synchronized (this) { notifyAll(); } } } } ././@LongLink0100644 0000000 0000000 00000000204 12302131605 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestMinimalClientRequestExecution.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestMin0100644 0000000 0000000 00000007446 12301751657 032537 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.IOException; import java.util.HashSet; import java.util.Locale; import java.util.Set; import org.apache.http.Header; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClients; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * Client protocol handling tests. */ public class TestMinimalClientRequestExecution extends IntegrationTestBase { @Before public void setUp() throws Exception { startServer(); } private static class SimpleService implements HttpRequestHandler { public SimpleService() { super(); } public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("Whatever"); response.setEntity(entity); } } @Test public void testNonCompliantURI() throws Exception { this.localServer.register("*", new SimpleService()); this.httpclient = HttpClients.createMinimal(); final HttpClientContext context = HttpClientContext.create(); for (int i = 0; i < 10; i++) { final HttpGet request = new HttpGet("/"); final HttpResponse response = this.httpclient.execute(getServerHttp(), request, context); EntityUtils.consume(response.getEntity()); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); final HttpRequest reqWrapper = context.getRequest(); Assert.assertNotNull(reqWrapper); final Header[] headers = reqWrapper.getAllHeaders(); final Set headerSet = new HashSet(); for (final Header header: headers) { headerSet.add(header.getName().toLowerCase(Locale.US)); } Assert.assertEquals(3, headerSet.size()); Assert.assertTrue(headerSet.contains("connection")); Assert.assertTrue(headerSet.contains("host")); Assert.assertTrue(headerSet.contains("user-agent")); } } } ././@LongLink0100644 0000000 0000000 00000000160 12302131605 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestRedirects.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestRed0100644 0000000 0000000 00000070607 12301751657 032525 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.IOException; import java.net.URI; import java.util.Arrays; import java.util.List; import org.apache.http.Header; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpInetConnection; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.ProtocolException; import org.apache.http.client.CircularRedirectException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CookieStore; import org.apache.http.client.RedirectException; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.URIUtils; import org.apache.http.cookie.SM; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.cookie.BasicClientCookie; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpCoreContext; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * Redirection test cases. */ public class TestRedirects extends IntegrationTestBase { @Before public void setUp() throws Exception { startServer(); this.httpclient = HttpClients.createDefault(); } private static class BasicRedirectService implements HttpRequestHandler { private final int statuscode; public BasicRedirectService(final int statuscode) { super(); this.statuscode = statuscode > 0 ? statuscode : HttpStatus.SC_MOVED_TEMPORARILY; } public BasicRedirectService() { this(-1); } public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final HttpInetConnection conn = (HttpInetConnection) context.getAttribute(HttpCoreContext.HTTP_CONNECTION); final String localhost = conn.getLocalAddress().getHostName(); final int port = conn.getLocalPort(); final String uri = request.getRequestLine().getUri(); if (uri.equals("/oldlocation/")) { response.setStatusCode(this.statuscode); response.addHeader(new BasicHeader("Location", "http://" + localhost + ":" + port + "/newlocation/")); response.addHeader(new BasicHeader("Connection", "close")); } else if (uri.equals("/newlocation/")) { response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("Successful redirect"); response.setEntity(entity); } else { response.setStatusCode(HttpStatus.SC_NOT_FOUND); } } } private static class CircularRedirectService implements HttpRequestHandler { public CircularRedirectService() { super(); } public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final String uri = request.getRequestLine().getUri(); if (uri.startsWith("/circular-oldlocation")) { response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY); response.addHeader(new BasicHeader("Location", "/circular-location2")); } else if (uri.startsWith("/circular-location2")) { response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY); response.addHeader(new BasicHeader("Location", "/circular-oldlocation")); } else { response.setStatusCode(HttpStatus.SC_NOT_FOUND); } } } private static class RelativeRedirectService implements HttpRequestHandler { public RelativeRedirectService() { super(); } public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final String uri = request.getRequestLine().getUri(); if (uri.equals("/oldlocation/")) { response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY); response.addHeader(new BasicHeader("Location", "/relativelocation/")); } else if (uri.equals("/relativelocation/")) { response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("Successful redirect"); response.setEntity(entity); } else { response.setStatusCode(HttpStatus.SC_NOT_FOUND); } } } private static class RelativeRedirectService2 implements HttpRequestHandler { public RelativeRedirectService2() { super(); } public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final String uri = request.getRequestLine().getUri(); if (uri.equals("/test/oldlocation")) { response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY); response.addHeader(new BasicHeader("Location", "relativelocation")); } else if (uri.equals("/test/relativelocation")) { response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("Successful redirect"); response.setEntity(entity); } else { response.setStatusCode(HttpStatus.SC_NOT_FOUND); } } } private static class RomeRedirectService implements HttpRequestHandler { public RomeRedirectService() { super(); } public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final String uri = request.getRequestLine().getUri(); if (uri.equals("/rome")) { response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("Successful redirect"); response.setEntity(entity); } else { response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY); response.addHeader(new BasicHeader("Location", "/rome")); } } } private static class BogusRedirectService implements HttpRequestHandler { private final String url; public BogusRedirectService(final String redirectUrl) { super(); this.url = redirectUrl; } public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final String uri = request.getRequestLine().getUri(); if (uri.equals("/oldlocation/")) { response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY); response.addHeader(new BasicHeader("Location", url)); } else if (uri.equals("/relativelocation/")) { response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("Successful redirect"); response.setEntity(entity); } else { response.setStatusCode(HttpStatus.SC_NOT_FOUND); } } } @Test public void testBasicRedirect300() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new BasicRedirectService(HttpStatus.SC_MULTIPLE_CHOICES)); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("/oldlocation/"); final HttpResponse response = this.httpclient.execute(target, httpget, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); Assert.assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, response.getStatusLine().getStatusCode()); Assert.assertEquals("/oldlocation/", reqWrapper.getRequestLine().getUri()); final List redirects = context.getRedirectLocations(); Assert.assertNull(redirects); } @Test public void testBasicRedirect301() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new BasicRedirectService(HttpStatus.SC_MOVED_PERMANENTLY)); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("/oldlocation/"); final HttpResponse response = this.httpclient.execute(target, httpget, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); final HttpHost host = context.getTargetHost(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri()); Assert.assertEquals(target, host); final List redirects = context.getRedirectLocations(); Assert.assertNotNull(redirects); Assert.assertEquals(1, redirects.size()); final URI redirect = URIUtils.rewriteURI(new URI("/newlocation/"), target); Assert.assertTrue(redirects.contains(redirect)); } @Test public void testBasicRedirect302() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new BasicRedirectService(HttpStatus.SC_MOVED_TEMPORARILY)); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("/oldlocation/"); final HttpResponse response = this.httpclient.execute(target, httpget, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); final HttpHost host = context.getTargetHost(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri()); Assert.assertEquals(target, host); } @Test public void testBasicRedirect302NoLocation() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new HttpRequestHandler() { public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY); } }); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("/oldlocation/"); final HttpResponse response = this.httpclient.execute(target, httpget, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); final HttpHost host = context.getTargetHost(); Assert.assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, response.getStatusLine().getStatusCode()); Assert.assertEquals("/oldlocation/", reqWrapper.getRequestLine().getUri()); Assert.assertEquals(target, host); } @Test public void testBasicRedirect303() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new BasicRedirectService(HttpStatus.SC_SEE_OTHER)); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("/oldlocation/"); final HttpResponse response = this.httpclient.execute(target, httpget, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); final HttpHost host = context.getTargetHost(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri()); Assert.assertEquals(target, host); } @Test public void testBasicRedirect304() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new BasicRedirectService(HttpStatus.SC_NOT_MODIFIED)); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("/oldlocation/"); final HttpResponse response = this.httpclient.execute(target, httpget, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, response.getStatusLine().getStatusCode()); Assert.assertEquals("/oldlocation/", reqWrapper.getRequestLine().getUri()); } @Test public void testBasicRedirect305() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new BasicRedirectService(HttpStatus.SC_USE_PROXY)); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("/oldlocation/"); final HttpResponse response = this.httpclient.execute(target, httpget, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); Assert.assertEquals(HttpStatus.SC_USE_PROXY, response.getStatusLine().getStatusCode()); Assert.assertEquals("/oldlocation/", reqWrapper.getRequestLine().getUri()); } @Test public void testBasicRedirect307() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new BasicRedirectService(HttpStatus.SC_TEMPORARY_REDIRECT)); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("/oldlocation/"); final HttpResponse response = this.httpclient.execute(target, httpget, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); final HttpHost host = context.getTargetHost(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri()); Assert.assertEquals(target, host); } @Test(expected=ClientProtocolException.class) public void testMaxRedirectCheck() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new CircularRedirectService()); final RequestConfig config = RequestConfig.custom() .setCircularRedirectsAllowed(true) .setMaxRedirects(5) .build(); final HttpGet httpget = new HttpGet("/circular-oldlocation/"); httpget.setConfig(config); try { this.httpclient.execute(target, httpget); } catch (final ClientProtocolException e) { Assert.assertTrue(e.getCause() instanceof RedirectException); throw e; } } @Test(expected=ClientProtocolException.class) public void testCircularRedirect() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new CircularRedirectService()); final RequestConfig config = RequestConfig.custom() .setCircularRedirectsAllowed(false) .build(); final HttpGet httpget = new HttpGet("/circular-oldlocation/"); httpget.setConfig(config); try { this.httpclient.execute(target, httpget); } catch (final ClientProtocolException e) { Assert.assertTrue(e.getCause() instanceof CircularRedirectException); throw e; } } @Test public void testRepeatRequest() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new RomeRedirectService()); final HttpClientContext context = HttpClientContext.create(); final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(true).build(); final HttpGet first = new HttpGet("/rome"); first.setConfig(config); EntityUtils.consume(this.httpclient.execute(target, first, context).getEntity()); final HttpGet second = new HttpGet("/rome"); second.setConfig(config); final HttpResponse response = this.httpclient.execute(target, second, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); final HttpHost host = context.getTargetHost(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals("/rome", reqWrapper.getRequestLine().getUri()); Assert.assertEquals(host, target); } @Test public void testRepeatRequestRedirect() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new RomeRedirectService()); final HttpClientContext context = HttpClientContext.create(); final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(true).build(); final HttpGet first = new HttpGet("/lille"); first.setConfig(config); final HttpResponse response1 = this.httpclient.execute(target, first, context); EntityUtils.consume(response1.getEntity()); final HttpGet second = new HttpGet("/lille"); second.setConfig(config); final HttpResponse response2 = this.httpclient.execute(target, second, context); EntityUtils.consume(response2.getEntity()); final HttpRequest reqWrapper = context.getRequest(); final HttpHost host = context.getTargetHost(); Assert.assertEquals(HttpStatus.SC_OK, response2.getStatusLine().getStatusCode()); Assert.assertEquals("/rome", reqWrapper.getRequestLine().getUri()); Assert.assertEquals(host, target); } @Test public void testDifferentRequestSameRedirect() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new RomeRedirectService()); final HttpClientContext context = HttpClientContext.create(); final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(true).build(); final HttpGet first = new HttpGet("/alian"); first.setConfig(config); final HttpResponse response1 = this.httpclient.execute(target, first, context); EntityUtils.consume(response1.getEntity()); final HttpGet second = new HttpGet("/lille"); second.setConfig(config); final HttpResponse response2 = this.httpclient.execute(target, second, context); EntityUtils.consume(response2.getEntity()); final HttpRequest reqWrapper = context.getRequest(); final HttpHost host = context.getTargetHost(); Assert.assertEquals(HttpStatus.SC_OK, response2.getStatusLine().getStatusCode()); Assert.assertEquals("/rome", reqWrapper.getRequestLine().getUri()); Assert.assertEquals(host, target); } @Test public void testPostNoRedirect() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new BasicRedirectService()); final HttpClientContext context = HttpClientContext.create(); final HttpPost httppost = new HttpPost("/oldlocation/"); httppost.setEntity(new StringEntity("stuff")); final HttpResponse response = this.httpclient.execute(target, httppost, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); Assert.assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, response.getStatusLine().getStatusCode()); Assert.assertEquals("/oldlocation/", reqWrapper.getRequestLine().getUri()); Assert.assertEquals("POST", reqWrapper.getRequestLine().getMethod()); } @Test public void testPostRedirectSeeOther() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new BasicRedirectService(HttpStatus.SC_SEE_OTHER)); final HttpClientContext context = HttpClientContext.create(); final HttpPost httppost = new HttpPost("/oldlocation/"); httppost.setEntity(new StringEntity("stuff")); final HttpResponse response = this.httpclient.execute(target, httppost, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri()); Assert.assertEquals("GET", reqWrapper.getRequestLine().getMethod()); } @Test public void testRelativeRedirect() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new RelativeRedirectService()); final HttpClientContext context = HttpClientContext.create(); final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(true).build(); final HttpGet httpget = new HttpGet("/oldlocation/"); httpget.setConfig(config); final HttpResponse response = this.httpclient.execute(target, httpget, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); final HttpHost host = context.getTargetHost(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals("/relativelocation/", reqWrapper.getRequestLine().getUri()); Assert.assertEquals(host, target); } @Test public void testRelativeRedirect2() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new RelativeRedirectService2()); final HttpClientContext context = HttpClientContext.create(); final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(true).build(); final HttpGet httpget = new HttpGet("/test/oldlocation"); httpget.setConfig(config); final HttpResponse response = this.httpclient.execute(target, httpget, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); final HttpHost host = context.getTargetHost(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals("/test/relativelocation", reqWrapper.getRequestLine().getUri()); Assert.assertEquals(host, target); } @Test(expected=ClientProtocolException.class) public void testRejectRelativeRedirect() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new RelativeRedirectService()); final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(false).build(); final HttpGet httpget = new HttpGet("/oldlocation/"); httpget.setConfig(config); try { this.httpclient.execute(target, httpget); } catch (final ClientProtocolException e) { Assert.assertTrue(e.getCause() instanceof ProtocolException); throw e; } } @Test(expected=ClientProtocolException.class) public void testRejectBogusRedirectLocation() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new BogusRedirectService("xxx://bogus")); final HttpGet httpget = new HttpGet("/oldlocation/"); try { this.httpclient.execute(target, httpget); } catch (final ClientProtocolException ex) { final Throwable cause = ex.getCause(); Assert.assertTrue(cause instanceof HttpException); throw ex; } } @Test(expected=ClientProtocolException.class) public void testRejectInvalidRedirectLocation() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new BogusRedirectService("http://" + target.toHostString() + "/newlocation/?p=I have spaces")); final HttpGet httpget = new HttpGet("/oldlocation/"); try { this.httpclient.execute(target, httpget); } catch (final ClientProtocolException e) { Assert.assertTrue(e.getCause() instanceof ProtocolException); throw e; } } @Test public void testRedirectWithCookie() throws Exception { final HttpHost target = getServerHttp(); this.localServer.register("*", new BasicRedirectService()); final CookieStore cookieStore = new BasicCookieStore(); final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain(target.getHostName()); cookie.setPath("/"); cookieStore.addCookie(cookie); final HttpClientContext context = HttpClientContext.create(); context.setCookieStore(cookieStore); final HttpGet httpget = new HttpGet("/oldlocation/"); final HttpResponse response = this.httpclient.execute(target, httpget, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri()); final Header[] headers = reqWrapper.getHeaders(SM.COOKIE); Assert.assertEquals("There can only be one (cookie)", 1, headers.length); } @Test public void testDefaultHeadersRedirect() throws Exception { this.httpclient = HttpClients.custom() .setDefaultHeaders(Arrays.asList(new BasicHeader(HTTP.USER_AGENT, "my-test-client"))) .build(); final HttpHost target = getServerHttp(); this.localServer.register("*", new BasicRedirectService()); final HttpClientContext context = HttpClientContext.create(); final HttpGet httpget = new HttpGet("/oldlocation/"); final HttpResponse response = this.httpclient.execute(target, httpget, context); EntityUtils.consume(response.getEntity()); final HttpRequest reqWrapper = context.getRequest(); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri()); final Header header = reqWrapper.getFirstHeader(HTTP.USER_AGENT); Assert.assertEquals("my-test-client", header.getValue()); } } ././@LongLink0100644 0000000 0000000 00000000163 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestSPNegoScheme.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestSPN0100644 0000000 0000000 00000020021 12301751657 032434 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.IOException; import java.security.Principal; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.AuthSchemes; import org.apache.http.client.methods.HttpGet; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.entity.StringEntity; import org.apache.http.impl.auth.SPNegoScheme; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.util.EntityUtils; import org.ietf.jgss.GSSContext; import org.ietf.jgss.GSSCredential; import org.ietf.jgss.GSSManager; import org.ietf.jgss.GSSName; import org.ietf.jgss.Oid; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Matchers; import org.mockito.Mockito; /** * Tests for {@link SPNegoScheme}. */ public class TestSPNegoScheme extends IntegrationTestBase { @Before public void setUp() throws Exception { startServer(); } /** * This service will continue to ask for authentication. */ private static class PleaseNegotiateService implements HttpRequestHandler { public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { response.setStatusCode(HttpStatus.SC_UNAUTHORIZED); response.addHeader(new BasicHeader("WWW-Authenticate", "Negotiate blablabla")); response.addHeader(new BasicHeader("Connection", "Keep-Alive")); response.setEntity(new StringEntity("auth required ")); } } /** * NegotatieScheme with a custom GSSManager that does not require any Jaas or * Kerberos configuration. * */ private static class NegotiateSchemeWithMockGssManager extends SPNegoScheme { GSSManager manager = Mockito.mock(GSSManager.class); GSSName name = Mockito.mock(GSSName.class); GSSContext context = Mockito.mock(GSSContext.class); NegotiateSchemeWithMockGssManager() throws Exception { super(true); Mockito.when(context.initSecContext( Matchers.any(byte[].class), Matchers.anyInt(), Matchers.anyInt())) .thenReturn("12345678".getBytes()); Mockito.when(manager.createName( Matchers.any(String.class), Matchers.any(Oid.class))) .thenReturn(name); Mockito.when(manager.createContext( Matchers.any(GSSName.class), Matchers.any(Oid.class), Matchers.any(GSSCredential.class), Matchers.anyInt())) .thenReturn(context); } @Override protected GSSManager getManager() { return manager; } } private static class UseJaasCredentials implements Credentials { public String getPassword() { return null; } public Principal getUserPrincipal() { return null; } } private static class NegotiateSchemeProviderWithMockGssManager implements AuthSchemeProvider { NegotiateSchemeWithMockGssManager scheme; NegotiateSchemeProviderWithMockGssManager() throws Exception { scheme = new NegotiateSchemeWithMockGssManager(); } public AuthScheme create(final HttpContext context) { return scheme; } } /** * Tests that the client will stop connecting to the server if * the server still keep asking for a valid ticket. */ @Test public void testDontTryToAuthenticateEndlessly() throws Exception { final int port = this.localServer.getServiceAddress().getPort(); this.localServer.register("*", new PleaseNegotiateService()); final HttpHost target = new HttpHost("localhost", port); final AuthSchemeProvider nsf = new NegotiateSchemeProviderWithMockGssManager(); final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); final Credentials use_jaas_creds = new UseJaasCredentials(); credentialsProvider.setCredentials(new AuthScope(null, -1, null), use_jaas_creds); final Registry authSchemeRegistry = RegistryBuilder.create() .register(AuthSchemes.SPNEGO, nsf) .build(); this.httpclient = HttpClients.custom() .setDefaultAuthSchemeRegistry(authSchemeRegistry) .setDefaultCredentialsProvider(credentialsProvider) .build(); final String s = "/path"; final HttpGet httpget = new HttpGet(s); final HttpResponse response = this.httpclient.execute(target, httpget); EntityUtils.consume(response.getEntity()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode()); } /** * Javadoc specifies that {@link GSSContext#initSecContext(byte[], int, int)} can return null * if no token is generated. Client should be able to deal with this response. */ @Test public void testNoTokenGeneratedError() throws Exception { final int port = this.localServer.getServiceAddress().getPort(); this.localServer.register("*", new PleaseNegotiateService()); final HttpHost target = new HttpHost("localhost", port); final AuthSchemeProvider nsf = new NegotiateSchemeProviderWithMockGssManager(); final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); final Credentials use_jaas_creds = new UseJaasCredentials(); credentialsProvider.setCredentials(new AuthScope(null, -1, null), use_jaas_creds); final Registry authSchemeRegistry = RegistryBuilder.create() .register(AuthSchemes.SPNEGO, nsf) .build(); this.httpclient = HttpClients.custom() .setDefaultAuthSchemeRegistry(authSchemeRegistry) .setDefaultCredentialsProvider(credentialsProvider) .build(); final String s = "/path"; final HttpGet httpget = new HttpGet(s); final HttpResponse response = this.httpclient.execute(target, httpget); EntityUtils.consume(response.getEntity()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode()); } } ././@LongLink0100644 0000000 0000000 00000000175 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestStatefulConnManagement.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/client/integration/TestSta0100644 0000000 0000000 00000024350 12301751657 032534 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.integration; import java.io.IOException; import org.apache.http.HttpClientConnection; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.UserTokenHandler; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * Test cases for state-ful connections. */ public class TestStatefulConnManagement extends IntegrationTestBase { @Before public void setUp() throws Exception { startServer(); } private static class SimpleService implements HttpRequestHandler { public SimpleService() { super(); } public void handle( final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { response.setStatusCode(HttpStatus.SC_OK); final StringEntity entity = new StringEntity("Whatever"); response.setEntity(entity); } } @Test public void testStatefulConnections() throws Exception { final int workerCount = 5; final int requestCount = 5; final int port = this.localServer.getServiceAddress().getPort(); this.localServer.register("*", new SimpleService()); final HttpHost target = new HttpHost("localhost", port); final PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager(); mgr.setMaxTotal(workerCount); mgr.setDefaultMaxPerRoute(workerCount); final UserTokenHandler userTokenHandler = new UserTokenHandler() { public Object getUserToken(final HttpContext context) { final String id = (String) context.getAttribute("user"); return id; } }; this.httpclient = HttpClients.custom() .setConnectionManager(mgr) .setUserTokenHandler(userTokenHandler) .build(); final HttpClientContext[] contexts = new HttpClientContext[workerCount]; final HttpWorker[] workers = new HttpWorker[workerCount]; for (int i = 0; i < contexts.length; i++) { final HttpClientContext context = HttpClientContext.create(); contexts[i] = context; workers[i] = new HttpWorker( "user" + i, context, requestCount, target, this.httpclient); } for (final HttpWorker worker : workers) { worker.start(); } for (final HttpWorker worker : workers) { worker.join(10000); } for (final HttpWorker worker : workers) { final Exception ex = worker.getException(); if (ex != null) { throw ex; } Assert.assertEquals(requestCount, worker.getCount()); } for (final HttpContext context : contexts) { final String uid = (String) context.getAttribute("user"); for (int r = 0; r < requestCount; r++) { final String state = (String) context.getAttribute("r" + r); Assert.assertNotNull(state); Assert.assertEquals(uid, state); } } } static class HttpWorker extends Thread { private final String uid; private final HttpClientContext context; private final int requestCount; private final HttpHost target; private final HttpClient httpclient; private volatile Exception exception; private volatile int count; public HttpWorker( final String uid, final HttpClientContext context, final int requestCount, final HttpHost target, final HttpClient httpclient) { super(); this.uid = uid; this.context = context; this.requestCount = requestCount; this.target = target; this.httpclient = httpclient; this.count = 0; } public int getCount() { return this.count; } public Exception getException() { return this.exception; } @Override public void run() { try { this.context.setAttribute("user", this.uid); for (int r = 0; r < this.requestCount; r++) { final HttpGet httpget = new HttpGet("/"); final HttpResponse response = this.httpclient.execute( this.target, httpget, this.context); this.count++; final HttpClientConnection conn = this.context.getConnection(HttpClientConnection.class); final HttpContext connContext = (HttpContext) conn; String connuid = (String) connContext.getAttribute("user"); if (connuid == null) { connContext.setAttribute("user", this.uid); connuid = this.uid; } this.context.setAttribute("r" + r, connuid); EntityUtils.consume(response.getEntity()); } } catch (final Exception ex) { this.exception = ex; } } } @Test public void testRouteSpecificPoolRecylcing() throws Exception { // This tests what happens when a maxed connection pool needs // to kill the last idle connection to a route to build a new // one to the same route. final int maxConn = 2; final int port = this.localServer.getServiceAddress().getPort(); this.localServer.register("*", new SimpleService()); // We build a client with 2 max active // connections, and 2 max per route. final PoolingHttpClientConnectionManager connMngr = new PoolingHttpClientConnectionManager(); connMngr.setMaxTotal(maxConn); connMngr.setDefaultMaxPerRoute(maxConn); final UserTokenHandler userTokenHandler = new UserTokenHandler() { public Object getUserToken(final HttpContext context) { return context.getAttribute("user"); } }; this.httpclient = HttpClients.custom() .setConnectionManager(connMngr) .setUserTokenHandler(userTokenHandler) .build(); // Bottom of the pool : a *keep alive* connection to Route 1. final HttpContext context1 = new BasicHttpContext(); context1.setAttribute("user", "stuff"); final HttpResponse response1 = this.httpclient.execute( new HttpHost("localhost", port), new HttpGet("/"), context1); EntityUtils.consume(response1.getEntity()); // The ConnPoolByRoute now has 1 free connection, out of 2 max // The ConnPoolByRoute has one RouteSpcfcPool, that has one free connection // for [localhost][stuff] Thread.sleep(100); // Send a very simple HTTP get (it MUST be simple, no auth, no proxy, no 302, no 401, ...) // Send it to another route. Must be a keepalive. final HttpContext context2 = new BasicHttpContext(); final HttpResponse response2 = this.httpclient.execute( new HttpHost("127.0.0.1", port), new HttpGet("/"), context2); EntityUtils.consume(response2.getEntity()); // ConnPoolByRoute now has 2 free connexions, out of its 2 max. // The [localhost][stuff] RouteSpcfcPool is the same as earlier // And there is a [127.0.0.1][null] pool with 1 free connection Thread.sleep(100); // This will put the ConnPoolByRoute to the targeted state : // [localhost][stuff] will not get reused because this call is [localhost][null] // So the ConnPoolByRoute will need to kill one connection (it is maxed out globally). // The killed conn is the oldest, which means the first HTTPGet ([localhost][stuff]). // When this happens, the RouteSpecificPool becomes empty. final HttpContext context3 = new BasicHttpContext(); final HttpResponse response3 = this.httpclient.execute( new HttpHost("localhost", port), new HttpGet("/"), context3); // If the ConnPoolByRoute did not behave coherently with the RouteSpecificPool // this may fail. Ex : if the ConnPool discared the route pool because it was empty, // but still used it to build the request3 connection. EntityUtils.consume(response3.getEntity()); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/0040755 0000000 0000000 00000000000 12301751656 026354 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000153 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/SessionInputBufferMock.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/SessionInputBufferMoc0100644 0000000 0000000 00000007232 12301751656 032534 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import org.apache.http.config.MessageConstraints; import org.apache.http.impl.io.HttpTransportMetricsImpl; import org.apache.http.impl.io.SessionInputBufferImpl; /** * {@link org.apache.http.io.SessionInputBuffer} mockup implementation. */ public class SessionInputBufferMock extends SessionInputBufferImpl { public static final int BUFFER_SIZE = 16; public SessionInputBufferMock( final InputStream instream, final int buffersize, final MessageConstraints constrains, final CharsetDecoder decoder) { super(new HttpTransportMetricsImpl(), buffersize, -1, constrains, decoder); bind(instream); } public SessionInputBufferMock( final InputStream instream, final int buffersize) { this(instream, buffersize, null, null); } public SessionInputBufferMock( final byte[] bytes, final int buffersize, final MessageConstraints constrains, final CharsetDecoder decoder) { this(new ByteArrayInputStream(bytes), buffersize, constrains, decoder); } public SessionInputBufferMock( final byte[] bytes, final int buffersize, final MessageConstraints constrains) { this(new ByteArrayInputStream(bytes), buffersize, constrains, null); } public SessionInputBufferMock( final byte[] bytes, final int buffersize) { this(new ByteArrayInputStream(bytes), buffersize); } public SessionInputBufferMock( final byte[] bytes) { this(bytes, BUFFER_SIZE); } public SessionInputBufferMock( final byte[] bytes, final Charset charset) { this(bytes, BUFFER_SIZE, null, charset != null ? charset.newDecoder() : null); } public SessionInputBufferMock( final byte[] bytes, final CharsetDecoder decoder) { this(bytes, BUFFER_SIZE, null, decoder); } public SessionInputBufferMock( final String s, final Charset charset) throws UnsupportedEncodingException { this(s.getBytes(charset.name()), charset); } @Override public boolean isDataAvailable(final int timeout) throws IOException { return true; } } ././@LongLink0100644 0000000 0000000 00000000171 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/TestBasicHttpClientConnectionManager.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/TestBasicHttpClientCo0100644 0000000 0000000 00000045673 12301751656 032455 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.util.concurrent.TimeUnit; import org.apache.http.HttpClientConnection; import org.apache.http.HttpHost; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.ConnectionConfig; import org.apache.http.config.Lookup; import org.apache.http.config.SocketConfig; import org.apache.http.conn.ConnectionRequest; import org.apache.http.conn.DnsResolver; import org.apache.http.conn.HttpConnectionFactory; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.conn.SchemePortResolver; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.LayeredConnectionSocketFactory; import org.apache.http.protocol.HttpContext; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; public class TestBasicHttpClientConnectionManager { @Mock private ManagedHttpClientConnection conn; @Mock private HttpConnectionFactory connFactory; @Mock private Lookup socketFactoryRegistry; @Mock private ConnectionSocketFactory plainSocketFactory; @Mock private LayeredConnectionSocketFactory sslSocketFactory; @Mock private Socket socket; @Mock private SchemePortResolver schemePortResolver; @Mock private DnsResolver dnsResolver; private BasicHttpClientConnectionManager mgr; @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); mgr = new BasicHttpClientConnectionManager( socketFactoryRegistry, connFactory, schemePortResolver, dnsResolver); } @Test public void testLeaseReleaseNonReusable() throws Exception { final HttpHost target = new HttpHost("localhost"); final HttpRoute route = new HttpRoute(target); Mockito.when(connFactory.create( Mockito.eq(route), Mockito.any())).thenReturn(conn); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn1); Assert.assertFalse(conn1.isOpen()); mgr.releaseConnection(conn1, null, 100, TimeUnit.MILLISECONDS); Assert.assertNull(mgr.getRoute()); Assert.assertNull(mgr.getState()); final ConnectionRequest connRequest2 = mgr.requestConnection(route, null); final HttpClientConnection conn2 = connRequest2.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn2); Assert.assertFalse(conn2.isOpen()); Mockito.verify(connFactory, Mockito.times(2)).create( Mockito.eq(route), Mockito.any()); } @Test public void testLeaseReleaseReusable() throws Exception { final HttpHost target = new HttpHost("somehost"); final HttpRoute route = new HttpRoute(target); Mockito.when(connFactory.create(Mockito.eq(route), Mockito.any())).thenReturn(conn); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn1); Mockito.verify(connFactory, Mockito.times(1)).create( Mockito.eq(route), Mockito.any()); Mockito.when(conn.isOpen()).thenReturn(Boolean.TRUE); mgr.releaseConnection(conn1, null, 10000, TimeUnit.MILLISECONDS); Assert.assertEquals(route, mgr.getRoute()); Assert.assertEquals(null, mgr.getState()); final ConnectionRequest connRequest2 = mgr.requestConnection(route, null); final HttpClientConnection conn2 = connRequest2.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn2); Assert.assertTrue(conn2.isOpen()); Mockito.verify(connFactory, Mockito.times(1)).create( Mockito.eq(route), Mockito.any()); } @Test public void testLeaseReleaseReusableWithState() throws Exception { final HttpHost target = new HttpHost("somehost"); final HttpRoute route = new HttpRoute(target); Mockito.when(connFactory.create( Mockito.eq(route), Mockito.any())).thenReturn(conn); final ConnectionRequest connRequest1 = mgr.requestConnection(route, "some state"); final HttpClientConnection conn1 = connRequest1.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn1); Mockito.verify(connFactory, Mockito.times(1)).create( Mockito.eq(route), Mockito.any()); Mockito.when(conn.isOpen()).thenReturn(Boolean.TRUE); mgr.releaseConnection(conn1, "some other state", 10000, TimeUnit.MILLISECONDS); Assert.assertEquals(route, mgr.getRoute()); Assert.assertEquals("some other state", mgr.getState()); final ConnectionRequest connRequest2 = mgr.requestConnection(route, "some other state"); final HttpClientConnection conn2 = connRequest2.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn2); Assert.assertTrue(conn2.isOpen()); Mockito.verify(connFactory, Mockito.times(1)).create( Mockito.eq(route), Mockito.any()); } @Test public void testLeaseDifferentRoute() throws Exception { final HttpHost target1 = new HttpHost("somehost"); final HttpRoute route1 = new HttpRoute(target1); Mockito.when(connFactory.create( Mockito.any(), Mockito.any())).thenReturn(conn); final ConnectionRequest connRequest1 = mgr.requestConnection(route1, null); final HttpClientConnection conn1 = connRequest1.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn1); Mockito.verify(connFactory, Mockito.times(1)).create( Mockito.eq(route1), Mockito.any()); Mockito.when(conn.isOpen()).thenReturn(Boolean.TRUE, Boolean.FALSE); mgr.releaseConnection(conn1, null, 0, TimeUnit.MILLISECONDS); Assert.assertEquals(route1, mgr.getRoute()); Assert.assertEquals(null, mgr.getState()); final HttpHost target2 = new HttpHost("otherhost"); final HttpRoute route2 = new HttpRoute(target2); final ConnectionRequest connRequest2 = mgr.requestConnection(route2, null); final HttpClientConnection conn2 = connRequest2.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn2); Assert.assertFalse(conn2.isOpen()); Mockito.verify(conn).close(); Mockito.verify(connFactory, Mockito.times(1)).create( Mockito.eq(route1), Mockito.any()); Mockito.verify(connFactory, Mockito.times(1)).create( Mockito.eq(route2), Mockito.any()); } @Test public void testLeaseExpired() throws Exception { final HttpHost target = new HttpHost("somehost"); final HttpRoute route = new HttpRoute(target); Mockito.when(connFactory.create( Mockito.eq(route), Mockito.any())).thenReturn(conn); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn1); Mockito.verify(connFactory, Mockito.times(1)).create( Mockito.eq(route), Mockito.any()); Mockito.when(conn.isOpen()).thenReturn(Boolean.TRUE, Boolean.FALSE); mgr.releaseConnection(conn1, null, 10, TimeUnit.MILLISECONDS); Assert.assertEquals(route, mgr.getRoute()); Assert.assertEquals(null, mgr.getState()); Thread.sleep(50); final ConnectionRequest connRequest2 = mgr.requestConnection(route, null); final HttpClientConnection conn2 = connRequest2.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn2); Assert.assertFalse(conn2.isOpen()); Mockito.verify(conn).close(); Mockito.verify(connFactory, Mockito.times(2)).create( Mockito.eq(route), Mockito.any()); } @Test(expected=IllegalArgumentException.class) public void testLeaseInvalidArg() throws Exception { mgr.requestConnection(null, null); } @Test(expected=IllegalArgumentException.class) public void testReleaseInvalidArg() throws Exception { mgr.releaseConnection(null, null, 0, TimeUnit.MILLISECONDS); } @Test(expected=IllegalStateException.class) public void testReleaseAnotherConnection() throws Exception { final HttpClientConnection wrongCon = Mockito.mock(HttpClientConnection.class); mgr.releaseConnection(wrongCon, null, 0, TimeUnit.MILLISECONDS); } @Test public void testShutdown() throws Exception { final HttpHost target = new HttpHost("somehost"); final HttpRoute route = new HttpRoute(target); Mockito.when(connFactory.create( Mockito.eq(route), Mockito.any())).thenReturn(conn); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn1); Mockito.verify(connFactory, Mockito.times(1)).create( Mockito.eq(route), Mockito.any()); Mockito.when(conn.isOpen()).thenReturn(Boolean.TRUE); mgr.releaseConnection(conn1, null, 0, TimeUnit.MILLISECONDS); mgr.shutdown(); Mockito.verify(conn, Mockito.times(1)).shutdown(); try { final ConnectionRequest connRequest2 = mgr.requestConnection(route, null); connRequest2.get(0, TimeUnit.MILLISECONDS); Assert.fail("IllegalStateException expected"); } catch (final IllegalStateException ex) { } // Should have no effect mgr.closeExpiredConnections(); mgr.closeIdleConnections(0L, TimeUnit.MILLISECONDS); mgr.shutdown(); Mockito.verify(conn, Mockito.times(1)).shutdown(); } @Test public void testCloseExpired() throws Exception { final HttpHost target = new HttpHost("somehost"); final HttpRoute route = new HttpRoute(target); Mockito.when(connFactory.create( Mockito.eq(route), Mockito.any())).thenReturn(conn); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn1); Mockito.verify(connFactory, Mockito.times(1)).create( Mockito.eq(route), Mockito.any()); Mockito.when(conn.isOpen()).thenReturn(Boolean.TRUE, Boolean.FALSE); mgr.releaseConnection(conn1, null, 10, TimeUnit.MILLISECONDS); Assert.assertEquals(route, mgr.getRoute()); Assert.assertEquals(null, mgr.getState()); Thread.sleep(50); mgr.closeExpiredConnections(); Mockito.verify(conn).close(); } @Test public void testCloseIdle() throws Exception { final HttpHost target = new HttpHost("somehost"); final HttpRoute route = new HttpRoute(target); Mockito.when(connFactory.create( Mockito.eq(route), Mockito.any())).thenReturn(conn); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn1); Mockito.verify(connFactory, Mockito.times(1)).create( Mockito.eq(route), Mockito.any()); Mockito.when(conn.isOpen()).thenReturn(Boolean.TRUE, Boolean.FALSE); mgr.releaseConnection(conn1, null, 0, TimeUnit.MILLISECONDS); Assert.assertEquals(route, mgr.getRoute()); Assert.assertEquals(null, mgr.getState()); Thread.sleep(100); mgr.closeIdleConnections(50, TimeUnit.MILLISECONDS); Mockito.verify(conn).close(); } @Test(expected=IllegalStateException.class) public void testAlreadyLeased() throws Exception { final HttpHost target = new HttpHost("somehost"); final HttpRoute route = new HttpRoute(target); Mockito.when(connFactory.create( Mockito.eq(route), Mockito.any())).thenReturn(conn); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn1); mgr.releaseConnection(conn1, null, 100, TimeUnit.MILLISECONDS); mgr.getConnection(route, null); mgr.getConnection(route, null); } @Test public void testTargetConnect() throws Exception { final HttpHost target = new HttpHost("somehost", -1, "https"); final InetAddress remote = InetAddress.getByAddress(new byte[] {10, 0, 0, 1}); final InetAddress local = InetAddress.getByAddress(new byte[] {127, 0, 0, 1}); final HttpRoute route = new HttpRoute(target, local, true); Mockito.when(connFactory.create( Mockito.eq(route), Mockito.any())).thenReturn(conn); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn1); final HttpClientContext context = HttpClientContext.create(); final SocketConfig sconfig = SocketConfig.custom().build(); mgr.setSocketConfig(sconfig); Mockito.when(dnsResolver.resolve("somehost")).thenReturn(new InetAddress[] {remote}); Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443); Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(plainSocketFactory); Mockito.when(plainSocketFactory.createSocket(Mockito.any())).thenReturn(socket); Mockito.when(plainSocketFactory.connectSocket( Mockito.anyInt(), Mockito.eq(socket), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(socket); mgr.connect(conn1, route, 123, context); Mockito.verify(dnsResolver, Mockito.times(1)).resolve("somehost"); Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target); Mockito.verify(plainSocketFactory, Mockito.times(1)).createSocket(context); Mockito.verify(plainSocketFactory, Mockito.times(1)).connectSocket(123, socket, target, new InetSocketAddress(remote, 8443), new InetSocketAddress(local, 0), context); mgr.routeComplete(conn1, route, context); } @Test public void testProxyConnectAndUpgrade() throws Exception { final HttpHost target = new HttpHost("somehost", -1, "https"); final HttpHost proxy = new HttpHost("someproxy", 8080); final InetAddress remote = InetAddress.getByAddress(new byte[] {10, 0, 0, 1}); final InetAddress local = InetAddress.getByAddress(new byte[] {127, 0, 0, 1}); final HttpRoute route = new HttpRoute(target, local, proxy, true); Mockito.when(connFactory.create( Mockito.eq(route), Mockito.any())).thenReturn(conn); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(0, TimeUnit.MILLISECONDS); Assert.assertNotNull(conn1); final HttpClientContext context = HttpClientContext.create(); final SocketConfig sconfig = SocketConfig.custom().build(); mgr.setSocketConfig(sconfig); Mockito.when(dnsResolver.resolve("someproxy")).thenReturn(new InetAddress[] {remote}); Mockito.when(schemePortResolver.resolve(proxy)).thenReturn(8080); Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443); Mockito.when(socketFactoryRegistry.lookup("http")).thenReturn(plainSocketFactory); Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(sslSocketFactory); Mockito.when(plainSocketFactory.createSocket(Mockito.any())).thenReturn(socket); Mockito.when(plainSocketFactory.connectSocket( Mockito.anyInt(), Mockito.eq(socket), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(socket); mgr.connect(conn1, route, 123, context); Mockito.verify(dnsResolver, Mockito.times(1)).resolve("someproxy"); Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(proxy); Mockito.verify(plainSocketFactory, Mockito.times(1)).createSocket(context); Mockito.verify(plainSocketFactory, Mockito.times(1)).connectSocket(123, socket, proxy, new InetSocketAddress(remote, 8080), new InetSocketAddress(local, 0), context); Mockito.when(conn.getSocket()).thenReturn(socket); mgr.upgrade(conn1, route, context); Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target); Mockito.verify(sslSocketFactory, Mockito.times(1)).createLayeredSocket( socket, "somehost", 8443, context); mgr.routeComplete(conn1, route, context); } } ././@LongLink0100644 0000000 0000000 00000000162 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/TestDefaultHttpResponseParser.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/TestDefaultHttpRespon0100644 0000000 0000000 00000010355 12301751656 032553 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import org.apache.http.Consts; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.NoHttpResponseException; import org.apache.http.ProtocolException; import org.apache.http.io.HttpMessageParser; import org.apache.http.io.SessionInputBuffer; import org.apache.http.util.CharArrayBuffer; import org.junit.Assert; import org.junit.Test; /** * Tests for {@link DefaultResponseParser}. */ public class TestDefaultHttpResponseParser { @Test public void testResponseParsingWithSomeGarbage() throws Exception { final String s = "garbage\r\n" + "garbage\r\n" + "more garbage\r\n" + "HTTP/1.1 200 OK\r\n" + "header1: value1\r\n" + "header2: value2\r\n" + "\r\n"; final SessionInputBuffer inbuffer = new SessionInputBufferMock(s, Consts.ASCII); final HttpMessageParser parser = new DefaultHttpResponseParser(inbuffer); final HttpResponse response = parser.parse(); Assert.assertNotNull(response); Assert.assertEquals(HttpVersion.HTTP_1_1, response.getProtocolVersion()); Assert.assertEquals(200, response.getStatusLine().getStatusCode()); final Header[] headers = response.getAllHeaders(); Assert.assertNotNull(headers); Assert.assertEquals(2, headers.length); Assert.assertEquals("header1", headers[0].getName()); Assert.assertEquals("header2", headers[1].getName()); } @Test(expected=ProtocolException.class) public void testResponseParsingWithTooMuchGarbage() throws Exception { final String s = "garbage\r\n" + "garbage\r\n" + "more garbage\r\n" + "HTTP/1.1 200 OK\r\n" + "header1: value1\r\n" + "header2: value2\r\n" + "\r\n"; final SessionInputBuffer inbuffer = new SessionInputBufferMock(s, Consts.ASCII); final HttpMessageParser parser = new DefaultHttpResponseParser(inbuffer) { @Override protected boolean reject(final CharArrayBuffer line, final int count) { return count >= 2; } }; parser.parse(); } @Test(expected=NoHttpResponseException.class) public void testResponseParsingNoResponse() throws Exception { final SessionInputBuffer inbuffer = new SessionInputBufferMock("", Consts.ASCII); final HttpMessageParser parser = new DefaultHttpResponseParser(inbuffer); parser.parse(); } @Test(expected=ProtocolException.class) public void testResponseParsingOnlyGarbage() throws Exception { final String s = "garbage\r\n" + "garbage\r\n" + "more garbage\r\n" + "a lot more garbage\r\n"; final SessionInputBuffer inbuffer = new SessionInputBufferMock(s, Consts.ASCII); final HttpMessageParser parser = new DefaultHttpResponseParser(inbuffer); parser.parse(); } } ././@LongLink0100644 0000000 0000000 00000000161 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/TestDefaultProxyRoutePlanner.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/TestDefaultProxyRoute0100644 0000000 0000000 00000007122 12301751656 032603 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpVersion; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.SchemePortResolver; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; /** * Tests for {@link DefaultProxyRoutePlanner}. */ public class TestDefaultProxyRoutePlanner { private HttpHost defaultProxy; private SchemePortResolver schemePortResolver; private DefaultProxyRoutePlanner routePlanner; @Before public void setup() { defaultProxy = new HttpHost("default.proxy.host", 8888); schemePortResolver = Mockito.mock(SchemePortResolver.class); routePlanner = new DefaultProxyRoutePlanner(defaultProxy, schemePortResolver); } @Test public void testDefaultProxyDirect() throws Exception { final HttpHost target = new HttpHost("somehost", 80, "http"); final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); final HttpContext context = new BasicHttpContext(); final HttpRoute route = routePlanner.determineRoute(target, request, context); Assert.assertEquals(target, route.getTargetHost()); Assert.assertEquals(defaultProxy, route.getProxyHost()); Assert.assertEquals(2, route.getHopCount()); Assert.assertFalse(route.isSecure()); } @Test public void testViaProxy() throws Exception { final HttpHost target = new HttpHost("somehost", 80, "http"); final HttpHost proxy = new HttpHost("custom.proxy.host", 8080); final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); final HttpClientContext context = HttpClientContext.create(); context.setRequestConfig(RequestConfig.custom().setProxy(proxy).build()); final HttpRoute route = routePlanner.determineRoute(target, request, context); Assert.assertEquals(target, route.getTargetHost()); Assert.assertEquals(proxy, route.getProxyHost()); Assert.assertEquals(2, route.getHopCount()); Assert.assertFalse(route.isSecure()); } } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/TestDefaultRoutePlanner.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/TestDefaultRoutePlann0100644 0000000 0000000 00000010257 12301751655 032534 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpVersion; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.SchemePortResolver; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; /** * Tests for {@link DefaultRoutePlanner}. */ public class TestDefaultRoutePlanner { private SchemePortResolver schemePortResolver; private DefaultRoutePlanner routePlanner; @Before public void setup() { schemePortResolver = Mockito.mock(SchemePortResolver.class); routePlanner = new DefaultRoutePlanner(schemePortResolver); } @Test public void testDirect() throws Exception { final HttpHost target = new HttpHost("somehost", 80, "http"); final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); final HttpContext context = new BasicHttpContext(); final HttpRoute route = routePlanner.determineRoute(target, request, context); Assert.assertEquals(target, route.getTargetHost()); Assert.assertEquals(1, route.getHopCount()); Assert.assertFalse(route.isSecure()); Mockito.verify(schemePortResolver, Mockito.never()).resolve(Mockito.any()); } @Test public void testDirectDefaultPort() throws Exception { final HttpHost target = new HttpHost("somehost", -1, "https"); Mockito.when(schemePortResolver.resolve(target)).thenReturn(443); final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); final HttpContext context = new BasicHttpContext(); final HttpRoute route = routePlanner.determineRoute(target, request, context); Assert.assertEquals(new HttpHost("somehost", 443, "https"), route.getTargetHost()); Assert.assertEquals(1, route.getHopCount()); Assert.assertTrue(route.isSecure()); } @Test public void testViaProxy() throws Exception { final HttpHost target = new HttpHost("somehost", 80, "http"); final HttpHost proxy = new HttpHost("proxy", 8080); final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); final HttpClientContext context = HttpClientContext.create(); context.setRequestConfig(RequestConfig.custom().setProxy(proxy).build()); final HttpRoute route = routePlanner.determineRoute(target, request, context); Assert.assertEquals(target, route.getTargetHost()); Assert.assertEquals(proxy, route.getProxyHost()); Assert.assertEquals(2, route.getHopCount()); Assert.assertFalse(route.isSecure()); Mockito.verify(schemePortResolver, Mockito.never()).resolve(Mockito.any()); } } ././@LongLink0100644 0000000 0000000 00000000165 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/TestHttpClientConnectionOperator.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/TestHttpClientConnect0100644 0000000 0000000 00000026135 12301751656 032533 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.net.ConnectException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketTimeoutException; import org.apache.http.HttpHost; import org.apache.http.config.Lookup; import org.apache.http.config.SocketConfig; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.DnsResolver; import org.apache.http.conn.HttpHostConnectException; import org.apache.http.conn.SchemePortResolver; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.conn.UnsupportedSchemeException; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.LayeredConnectionSocketFactory; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; public class TestHttpClientConnectionOperator { private ManagedHttpClientConnection conn; private Socket socket; private ConnectionSocketFactory plainSocketFactory; private LayeredConnectionSocketFactory sslSocketFactory; private Lookup socketFactoryRegistry; private SchemePortResolver schemePortResolver; private DnsResolver dnsResolver; private HttpClientConnectionOperator connectionOperator; @SuppressWarnings("unchecked") @Before public void setup() throws Exception { conn = Mockito.mock(ManagedHttpClientConnection.class); socket = Mockito.mock(Socket.class); plainSocketFactory = Mockito.mock(ConnectionSocketFactory.class); sslSocketFactory = Mockito.mock(LayeredConnectionSocketFactory.class); socketFactoryRegistry = Mockito.mock(Lookup.class); schemePortResolver = Mockito.mock(SchemePortResolver.class); dnsResolver = Mockito.mock(DnsResolver.class); connectionOperator = new HttpClientConnectionOperator( socketFactoryRegistry, schemePortResolver, dnsResolver); } @Test public void testConnect() throws Exception { final HttpContext context = new BasicHttpContext(); final HttpHost host = new HttpHost("somehost"); final InetAddress local = InetAddress.getByAddress(new byte[] {127, 0, 0, 0}); final InetAddress ip1 = InetAddress.getByAddress(new byte[] {127, 0, 0, 1}); final InetAddress ip2 = InetAddress.getByAddress(new byte[] {127, 0, 0, 2}); Mockito.when(dnsResolver.resolve("somehost")).thenReturn(new InetAddress[] { ip1, ip2 }); Mockito.when(socketFactoryRegistry.lookup("http")).thenReturn(plainSocketFactory); Mockito.when(schemePortResolver.resolve(host)).thenReturn(80); Mockito.when(plainSocketFactory.createSocket(Mockito.any())).thenReturn(socket); Mockito.when(plainSocketFactory.connectSocket( Mockito.anyInt(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(socket); final SocketConfig socketConfig = SocketConfig.custom() .setSoKeepAlive(true) .setSoReuseAddress(true) .setSoTimeout(5000) .setTcpNoDelay(true) .setSoLinger(50) .build(); final InetSocketAddress localAddress = new InetSocketAddress(local, 0); connectionOperator.connect(conn, host, localAddress, 1000, socketConfig, context); Mockito.verify(socket).setKeepAlive(true); Mockito.verify(socket).setReuseAddress(true); Mockito.verify(socket).setSoTimeout(5000); Mockito.verify(socket).setSoLinger(true, 50); Mockito.verify(socket).setTcpNoDelay(true); Mockito.verify(plainSocketFactory).connectSocket( 1000, socket, host, new InetSocketAddress(ip1, 80), localAddress, context); Mockito.verify(conn, Mockito.times(2)).bind(socket); } @Test(expected=ConnectTimeoutException.class) public void testConnectTimeout() throws Exception { final HttpContext context = new BasicHttpContext(); final HttpHost host = new HttpHost("somehost"); final InetAddress ip1 = InetAddress.getByAddress(new byte[] {10, 0, 0, 1}); final InetAddress ip2 = InetAddress.getByAddress(new byte[] {10, 0, 0, 2}); Mockito.when(dnsResolver.resolve("somehost")).thenReturn(new InetAddress[] { ip1, ip2 }); Mockito.when(socketFactoryRegistry.lookup("http")).thenReturn(plainSocketFactory); Mockito.when(schemePortResolver.resolve(host)).thenReturn(80); Mockito.when(plainSocketFactory.createSocket(Mockito.any())).thenReturn(socket); Mockito.when(plainSocketFactory.connectSocket( Mockito.anyInt(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenThrow(new SocketTimeoutException()); connectionOperator.connect(conn, host, null, 1000, SocketConfig.DEFAULT, context); } @Test(expected=HttpHostConnectException.class) public void testConnectFailure() throws Exception { final HttpContext context = new BasicHttpContext(); final HttpHost host = new HttpHost("somehost"); final InetAddress ip1 = InetAddress.getByAddress(new byte[] {10, 0, 0, 1}); final InetAddress ip2 = InetAddress.getByAddress(new byte[] {10, 0, 0, 2}); Mockito.when(dnsResolver.resolve("somehost")).thenReturn(new InetAddress[] { ip1, ip2 }); Mockito.when(socketFactoryRegistry.lookup("http")).thenReturn(plainSocketFactory); Mockito.when(schemePortResolver.resolve(host)).thenReturn(80); Mockito.when(plainSocketFactory.createSocket(Mockito.any())).thenReturn(socket); Mockito.when(plainSocketFactory.connectSocket( Mockito.anyInt(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenThrow(new ConnectException()); connectionOperator.connect(conn, host, null, 1000, SocketConfig.DEFAULT, context); } @Test public void testConnectFailover() throws Exception { final HttpContext context = new BasicHttpContext(); final HttpHost host = new HttpHost("somehost"); final InetAddress local = InetAddress.getByAddress(new byte[] {127, 0, 0, 0}); final InetAddress ip1 = InetAddress.getByAddress(new byte[] {10, 0, 0, 1}); final InetAddress ip2 = InetAddress.getByAddress(new byte[] {10, 0, 0, 2}); Mockito.when(dnsResolver.resolve("somehost")).thenReturn(new InetAddress[] { ip1, ip2 }); Mockito.when(socketFactoryRegistry.lookup("http")).thenReturn(plainSocketFactory); Mockito.when(schemePortResolver.resolve(host)).thenReturn(80); Mockito.when(plainSocketFactory.createSocket(Mockito.any())).thenReturn(socket); Mockito.when(plainSocketFactory.connectSocket( Mockito.anyInt(), Mockito.any(), Mockito.any(), Mockito.eq(new InetSocketAddress(ip1, 80)), Mockito.any(), Mockito.any())).thenThrow(new ConnectException()); Mockito.when(plainSocketFactory.connectSocket( Mockito.anyInt(), Mockito.any(), Mockito.any(), Mockito.eq(new InetSocketAddress(ip2, 80)), Mockito.any(), Mockito.any())).thenReturn(socket); final InetSocketAddress localAddress = new InetSocketAddress(local, 0); connectionOperator.connect(conn, host, localAddress, 1000, SocketConfig.DEFAULT, context); Mockito.verify(plainSocketFactory).connectSocket( 1000, socket, host, new InetSocketAddress(ip2, 80), localAddress, context); Mockito.verify(conn, Mockito.times(3)).bind(socket); } @Test public void testUpgrade() throws Exception { final HttpContext context = new BasicHttpContext(); final HttpHost host = new HttpHost("somehost", -1, "https"); Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(sslSocketFactory); Mockito.when(schemePortResolver.resolve(host)).thenReturn(443); Mockito.when(sslSocketFactory.createSocket(Mockito.any())).thenReturn(socket); Mockito.when(sslSocketFactory.createLayeredSocket( Mockito.any(), Mockito.eq("somehost"), Mockito.eq(443), Mockito.any())).thenReturn(socket); connectionOperator.upgrade(conn, host, context); Mockito.verify(conn).bind(socket); } @Test(expected=UnsupportedSchemeException.class) public void testUpgradeUpsupportedScheme() throws Exception { final HttpContext context = new BasicHttpContext(); final HttpHost host = new HttpHost("somehost", -1, "httpsssss"); Mockito.when(socketFactoryRegistry.lookup("http")).thenReturn(plainSocketFactory); connectionOperator.upgrade(conn, host, context); } @Test(expected=UnsupportedSchemeException.class) public void testUpgradeNonLayeringScheme() throws Exception { final HttpContext context = new BasicHttpContext(); final HttpHost host = new HttpHost("somehost", -1, "http"); Mockito.when(socketFactoryRegistry.lookup("http")).thenReturn(plainSocketFactory); connectionOperator.upgrade(conn, host, context); } } ././@LongLink0100644 0000000 0000000 00000000173 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/TestPoolingHttpClientConnectionManager.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/TestPoolingHttpClient0100644 0000000 0000000 00000036361 12301751656 032553 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpClientConnection; import org.apache.http.HttpHost; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.ConnectionConfig; import org.apache.http.config.Lookup; import org.apache.http.config.SocketConfig; import org.apache.http.conn.ConnectionPoolTimeoutException; import org.apache.http.conn.ConnectionRequest; import org.apache.http.conn.DnsResolver; import org.apache.http.conn.SchemePortResolver; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.LayeredConnectionSocketFactory; import org.apache.http.protocol.HttpContext; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; /** * {@link PoolingHttpClientConnectionManager} tests. */ public class TestPoolingHttpClientConnectionManager { @Mock private ManagedHttpClientConnection conn; @Mock private Lookup socketFactoryRegistry; @Mock private ConnectionSocketFactory plainSocketFactory; @Mock private ConnectionSocketFactory sslSocketFactory; @Mock private Socket socket; @Mock private SchemePortResolver schemePortResolver; @Mock private DnsResolver dnsResolver; @Mock private Future future; @Mock private CPool pool; private PoolingHttpClientConnectionManager mgr; @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); mgr = new PoolingHttpClientConnectionManager( pool, socketFactoryRegistry, schemePortResolver, dnsResolver); } @Test public void testLeaseRelease() throws Exception { final HttpHost target = new HttpHost("localhost"); final HttpRoute route = new HttpRoute(target); final CPoolEntry entry = new CPoolEntry(LogFactory.getLog(getClass()), "id", route, conn, -1, TimeUnit.MILLISECONDS); entry.markRouteComplete(); Mockito.when(future.isCancelled()).thenReturn(Boolean.FALSE); Mockito.when(socketFactoryRegistry.lookup("http")).thenReturn(plainSocketFactory); Mockito.when(schemePortResolver.resolve(target)).thenReturn(80); Mockito.when(plainSocketFactory.createSocket(Mockito.any())).thenReturn(socket); Mockito.when(conn.isOpen()).thenReturn(true); Mockito.when(future.isCancelled()).thenReturn(false); Mockito.when(future.get(1, TimeUnit.SECONDS)).thenReturn(entry); Mockito.when(pool.lease(route, null, null)).thenReturn(future); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(1, TimeUnit.SECONDS); Assert.assertNotNull(conn1); Assert.assertNotSame(conn, conn1); mgr.releaseConnection(conn1, null, 0, TimeUnit.MILLISECONDS); Mockito.verify(pool).release(entry, true); } @Test public void testReleaseRouteIncomplete() throws Exception { final HttpHost target = new HttpHost("localhost"); final HttpRoute route = new HttpRoute(target); final CPoolEntry entry = new CPoolEntry(LogFactory.getLog(getClass()), "id", route, conn, -1, TimeUnit.MILLISECONDS); Mockito.when(future.isCancelled()).thenReturn(Boolean.FALSE); Mockito.when(socketFactoryRegistry.lookup("http")).thenReturn(plainSocketFactory); Mockito.when(schemePortResolver.resolve(target)).thenReturn(80); Mockito.when(plainSocketFactory.createSocket(Mockito.any())).thenReturn(socket); Mockito.when(conn.isOpen()).thenReturn(true); Mockito.when(future.isCancelled()).thenReturn(false); Mockito.when(future.get(1, TimeUnit.SECONDS)).thenReturn(entry); Mockito.when(pool.lease(route, null, null)).thenReturn(future); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(1, TimeUnit.SECONDS); Assert.assertNotNull(conn1); Assert.assertNotSame(conn, conn1); mgr.releaseConnection(conn1, null, 0, TimeUnit.MILLISECONDS); Mockito.verify(pool).release(entry, false); } @Test(expected=InterruptedException.class) public void testLeaseFutureCancelled() throws Exception { final HttpHost target = new HttpHost("localhost"); final HttpRoute route = new HttpRoute(target); final CPoolEntry entry = new CPoolEntry(LogFactory.getLog(getClass()), "id", route, conn, -1, TimeUnit.MILLISECONDS); entry.markRouteComplete(); Mockito.when(future.isCancelled()).thenReturn(Boolean.TRUE); Mockito.when(future.get(1, TimeUnit.SECONDS)).thenReturn(entry); Mockito.when(pool.lease(route, null, null)).thenReturn(future); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); connRequest1.get(1, TimeUnit.SECONDS); } @Test(expected=ConnectionPoolTimeoutException.class) public void testLeaseFutureTimeout() throws Exception { final HttpHost target = new HttpHost("localhost"); final HttpRoute route = new HttpRoute(target); Mockito.when(future.isCancelled()).thenReturn(Boolean.TRUE); Mockito.when(future.get(1, TimeUnit.SECONDS)).thenThrow(new TimeoutException()); Mockito.when(pool.lease(route, null, null)).thenReturn(future); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); connRequest1.get(1, TimeUnit.SECONDS); } @Test public void testReleaseReusable() throws Exception { final HttpHost target = new HttpHost("localhost"); final HttpRoute route = new HttpRoute(target); final CPoolEntry entry = Mockito.spy(new CPoolEntry(LogFactory.getLog(getClass()), "id", route, conn, -1, TimeUnit.MILLISECONDS)); entry.markRouteComplete(); Mockito.when(future.isCancelled()).thenReturn(Boolean.FALSE); Mockito.when(future.get(1, TimeUnit.SECONDS)).thenReturn(entry); Mockito.when(pool.lease(route, null, null)).thenReturn(future); Mockito.when(conn.isOpen()).thenReturn(Boolean.TRUE); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(1, TimeUnit.SECONDS); Assert.assertNotNull(conn1); Assert.assertTrue(conn1.isOpen()); mgr.releaseConnection(conn1, "some state", 0, TimeUnit.MILLISECONDS); Mockito.verify(pool).release(entry, true); Mockito.verify(entry).setState("some state"); Mockito.verify(entry).updateExpiry(Mockito.anyLong(), Mockito.eq(TimeUnit.MILLISECONDS)); } @Test public void testReleaseNonReusable() throws Exception { final HttpHost target = new HttpHost("localhost"); final HttpRoute route = new HttpRoute(target); final CPoolEntry entry = Mockito.spy(new CPoolEntry(LogFactory.getLog(getClass()), "id", route, conn, -1, TimeUnit.MILLISECONDS)); entry.markRouteComplete(); Mockito.when(future.isCancelled()).thenReturn(Boolean.FALSE); Mockito.when(future.get(1, TimeUnit.SECONDS)).thenReturn(entry); Mockito.when(pool.lease(route, null, null)).thenReturn(future); Mockito.when(conn.isOpen()).thenReturn(Boolean.FALSE); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(1, TimeUnit.SECONDS); Assert.assertNotNull(conn1); Assert.assertFalse(conn1.isOpen()); mgr.releaseConnection(conn1, "some state", 0, TimeUnit.MILLISECONDS); Mockito.verify(pool).release(entry, false); Mockito.verify(entry, Mockito.never()).setState(Mockito.anyObject()); Mockito.verify(entry, Mockito.never()).updateExpiry(Mockito.anyLong(), Mockito.eq(TimeUnit.MILLISECONDS)); } @Test public void testTargetConnect() throws Exception { final HttpHost target = new HttpHost("somehost", -1, "https"); final InetAddress remote = InetAddress.getByAddress(new byte[] {10, 0, 0, 1}); final InetAddress local = InetAddress.getByAddress(new byte[]{127, 0, 0, 1}); final HttpRoute route = new HttpRoute(target, local, true); final CPoolEntry entry = new CPoolEntry(LogFactory.getLog(getClass()), "id", route, conn, -1, TimeUnit.MILLISECONDS); entry.markRouteComplete(); Mockito.when(future.isCancelled()).thenReturn(Boolean.FALSE); Mockito.when(conn.isOpen()).thenReturn(true); Mockito.when(future.isCancelled()).thenReturn(false); Mockito.when(future.get(1, TimeUnit.SECONDS)).thenReturn(entry); Mockito.when(pool.lease(route, null, null)).thenReturn(future); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(1, TimeUnit.SECONDS); Assert.assertNotNull(conn1); final HttpClientContext context = HttpClientContext.create(); final SocketConfig sconfig = SocketConfig.custom().build(); mgr.setDefaultSocketConfig(sconfig); Mockito.when(dnsResolver.resolve("somehost")).thenReturn(new InetAddress[]{remote}); Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443); Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(plainSocketFactory); Mockito.when(plainSocketFactory.createSocket(Mockito.any())).thenReturn(socket); Mockito.when(plainSocketFactory.connectSocket( Mockito.anyInt(), Mockito.eq(socket), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(socket); mgr.connect(conn1, route, 123, context); Mockito.verify(dnsResolver, Mockito.times(1)).resolve("somehost"); Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target); Mockito.verify(plainSocketFactory, Mockito.times(1)).createSocket(context); Mockito.verify(plainSocketFactory, Mockito.times(1)).connectSocket(123, socket, target, new InetSocketAddress(remote, 8443), new InetSocketAddress(local, 0), context); mgr.routeComplete(conn1, route, context); } @Test public void testProxyConnectAndUpgrade() throws Exception { final HttpHost target = new HttpHost("somehost", -1, "https"); final HttpHost proxy = new HttpHost("someproxy", 8080); final InetAddress remote = InetAddress.getByAddress(new byte[] {10, 0, 0, 1}); final InetAddress local = InetAddress.getByAddress(new byte[] {127, 0, 0, 1}); final HttpRoute route = new HttpRoute(target, local, proxy, true); final CPoolEntry entry = new CPoolEntry(LogFactory.getLog(getClass()), "id", route, conn, -1, TimeUnit.MILLISECONDS); entry.markRouteComplete(); Mockito.when(future.isCancelled()).thenReturn(Boolean.FALSE); Mockito.when(conn.isOpen()).thenReturn(true); Mockito.when(future.isCancelled()).thenReturn(false); Mockito.when(future.get(1, TimeUnit.SECONDS)).thenReturn(entry); Mockito.when(pool.lease(route, null, null)).thenReturn(future); final ConnectionRequest connRequest1 = mgr.requestConnection(route, null); final HttpClientConnection conn1 = connRequest1.get(1, TimeUnit.SECONDS); Assert.assertNotNull(conn1); final ConnectionSocketFactory plainsf = Mockito.mock(ConnectionSocketFactory.class); final LayeredConnectionSocketFactory sslsf = Mockito.mock(LayeredConnectionSocketFactory.class); final Socket socket = Mockito.mock(Socket.class); final HttpClientContext context = HttpClientContext.create(); final SocketConfig sconfig = SocketConfig.custom().build(); final ConnectionConfig cconfig = ConnectionConfig.custom().build(); mgr.setDefaultSocketConfig(sconfig); mgr.setDefaultConnectionConfig(cconfig); Mockito.when(dnsResolver.resolve("someproxy")).thenReturn(new InetAddress[] {remote}); Mockito.when(schemePortResolver.resolve(proxy)).thenReturn(8080); Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443); Mockito.when(socketFactoryRegistry.lookup("http")).thenReturn(plainsf); Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(sslsf); Mockito.when(plainsf.createSocket(Mockito.any())).thenReturn(socket); Mockito.when(plainsf.connectSocket( Mockito.anyInt(), Mockito.eq(socket), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(socket); mgr.connect(conn1, route, 123, context); Mockito.verify(dnsResolver, Mockito.times(1)).resolve("someproxy"); Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(proxy); Mockito.verify(plainsf, Mockito.times(1)).createSocket(context); Mockito.verify(plainsf, Mockito.times(1)).connectSocket(123, socket, proxy, new InetSocketAddress(remote, 8080), new InetSocketAddress(local, 0), context); Mockito.when(conn.getSocket()).thenReturn(socket); mgr.upgrade(conn1, route, context); Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target); Mockito.verify(sslsf, Mockito.times(1)).createLayeredSocket( socket, "somehost", 8443, context); mgr.routeComplete(conn1, route, context); } } ././@LongLink0100644 0000000 0000000 00000000162 12302131605 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/TestSystemDefaultRoutePlanner.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/conn/TestSystemDefaultRout0100644 0000000 0000000 00000011245 12301751656 032602 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.conn; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.ProxySelector; import java.net.URI; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpVersion; import org.apache.http.conn.SchemePortResolver; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; /** * Tests for {@link SystemDefaultRoutePlanner}. */ public class TestSystemDefaultRoutePlanner { private SchemePortResolver schemePortResolver; private ProxySelector proxySelector; private SystemDefaultRoutePlanner routePlanner; @Before public void setup() { schemePortResolver = Mockito.mock(SchemePortResolver.class); proxySelector = Mockito.mock(ProxySelector.class); routePlanner = new SystemDefaultRoutePlanner(schemePortResolver, proxySelector); } @Test public void testDirect() throws Exception { final HttpHost target = new HttpHost("somehost", 80, "http"); final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); final HttpContext context = new BasicHttpContext(); final HttpRoute route = routePlanner.determineRoute(target, request, context); Assert.assertEquals(target, route.getTargetHost()); Assert.assertEquals(1, route.getHopCount()); Assert.assertFalse(route.isSecure()); Mockito.verify(schemePortResolver, Mockito.never()).resolve(Mockito.any()); } @Test public void testDirectDefaultPort() throws Exception { final HttpHost target = new HttpHost("somehost", -1, "https"); Mockito.when(schemePortResolver.resolve(target)).thenReturn(443); final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); final HttpContext context = new BasicHttpContext(); final HttpRoute route = routePlanner.determineRoute(target, request, context); Assert.assertEquals(new HttpHost("somehost", 443, "https"), route.getTargetHost()); Assert.assertEquals(1, route.getHopCount()); Assert.assertTrue(route.isSecure()); } @Test public void testProxy() throws Exception { final InetAddress ia = InetAddress.getByAddress(new byte[] { (byte)127, (byte)0, (byte)0, (byte)1 }); final InetSocketAddress isa1 = new InetSocketAddress(ia, 11111); final InetSocketAddress isa2 = new InetSocketAddress(ia, 22222); final List proxies = new ArrayList(2); proxies.add(new Proxy(Proxy.Type.HTTP, isa1)); proxies.add(new Proxy(Proxy.Type.HTTP, isa2)); Mockito.when(proxySelector.select(new URI("http://somehost:80"))).thenReturn(proxies); final HttpHost target = new HttpHost("somehost", 80, "http"); final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); final HttpContext context = new BasicHttpContext(); final HttpRoute route = routePlanner.determineRoute(target, request, context); Assert.assertEquals(target, route.getTargetHost()); Assert.assertEquals(2, route.getHopCount()); Assert.assertEquals(isa1.getPort(), route.getProxyHost().getPort()); } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/0040755 0000000 0000000 00000000000 12301751655 026667 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000155 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestAbstractCookieSpec.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestAbstractCookieS0100644 0000000 0000000 00000011471 12301751655 032473 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.Iterator; import java.util.List; import org.apache.http.Header; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie; import org.junit.Assert; import org.junit.Test; public class TestAbstractCookieSpec { private static class DummyCookieSpec extends AbstractCookieSpec { public List

formatCookies(final List cookies) { return null; } public boolean match(final Cookie cookie, final CookieOrigin origin) { return true; } public List parse(final Header header, final CookieOrigin origin) throws MalformedCookieException { return null; } public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { } public int getVersion() { return 0; } public Header getVersionHeader() { return null; } } private static class DummyCookieAttribHandler implements CookieAttributeHandler { public boolean match(final Cookie cookie, final CookieOrigin origin) { return true; } public void parse(final SetCookie cookie, final String value) throws MalformedCookieException { } public void validate(final Cookie cookie, final CookieOrigin origin) throws MalformedCookieException { } } @Test public void testSimpleRegisterAndGet() { final CookieAttributeHandler h1 = new DummyCookieAttribHandler(); final CookieAttributeHandler h2 = new DummyCookieAttribHandler(); final AbstractCookieSpec cookiespec = new DummyCookieSpec(); cookiespec.registerAttribHandler("this", h1); cookiespec.registerAttribHandler("that", h2); cookiespec.registerAttribHandler("thistoo", h1); cookiespec.registerAttribHandler("thattoo", h2); Assert.assertTrue(h1 == cookiespec.getAttribHandler("this")); Assert.assertTrue(h2 == cookiespec.getAttribHandler("that")); Assert.assertTrue(h1 == cookiespec.getAttribHandler("thistoo")); Assert.assertTrue(h2 == cookiespec.getAttribHandler("thattoo")); final Iterator it = cookiespec.getAttribHandlers().iterator(); Assert.assertNotNull(it.next()); Assert.assertNotNull(it.next()); Assert.assertNotNull(it.next()); Assert.assertNotNull(it.next()); Assert.assertFalse(it.hasNext()); } @Test(expected=IllegalStateException.class) public void testInvalidHandler() { final CookieAttributeHandler h1 = new DummyCookieAttribHandler(); final CookieAttributeHandler h2 = new DummyCookieAttribHandler(); final AbstractCookieSpec cookiespec = new DummyCookieSpec(); cookiespec.registerAttribHandler("this", h1); cookiespec.registerAttribHandler("that", h2); Assert.assertNull(cookiespec.findAttribHandler("whatever")); cookiespec.getAttribHandler("whatever"); } @Test(expected=IllegalArgumentException.class) public void testBasicPathInvalidInput1() throws Exception { final AbstractCookieSpec cookiespec = new DummyCookieSpec(); cookiespec.registerAttribHandler(null, null); } @Test(expected=IllegalArgumentException.class) public void testBasicPathInvalidInput2() throws Exception { final AbstractCookieSpec cookiespec = new DummyCookieSpec(); cookiespec.registerAttribHandler("whatever", null); } } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestBasicClientCookie.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestBasicClientCook0100644 0000000 0000000 00000007256 12301751655 032455 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.junit.Assert; import org.junit.Test; /** * Unit tests for {@link BasicClientCookie}. */ public class TestBasicClientCookie { @Test public void testConstructor() { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); Assert.assertEquals("name", cookie.getName()); Assert.assertEquals("value", cookie.getValue()); try { new BasicClientCookie(null, null); Assert.fail("IllegalArgumentException should have been thrown"); } catch (final IllegalArgumentException ex) { //expected } } @Test public void testCloning() throws Exception { final BasicClientCookie orig = new BasicClientCookie("name", "value"); orig.setDomain("domain"); orig.setPath("/"); orig.setAttribute("attrib", "stuff"); final BasicClientCookie clone = (BasicClientCookie) orig.clone(); Assert.assertEquals(orig.getName(), clone.getName()); Assert.assertEquals(orig.getValue(), clone.getValue()); Assert.assertEquals(orig.getDomain(), clone.getDomain()); Assert.assertEquals(orig.getPath(), clone.getPath()); Assert.assertEquals(orig.getAttribute("attrib"), clone.getAttribute("attrib")); } @Test public void testSerialization() throws Exception { final BasicClientCookie orig = new BasicClientCookie("name", "value"); orig.setDomain("domain"); orig.setPath("/"); orig.setAttribute("attrib", "stuff"); final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream(); final ObjectOutputStream outstream = new ObjectOutputStream(outbuffer); outstream.writeObject(orig); outstream.close(); final byte[] raw = outbuffer.toByteArray(); final ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw); final ObjectInputStream instream = new ObjectInputStream(inbuffer); final BasicClientCookie clone = (BasicClientCookie) instream.readObject(); Assert.assertEquals(orig.getName(), clone.getName()); Assert.assertEquals(orig.getValue(), clone.getValue()); Assert.assertEquals(orig.getDomain(), clone.getDomain()); Assert.assertEquals(orig.getPath(), clone.getPath()); Assert.assertEquals(orig.getAttribute("attrib"), clone.getAttribute("attrib")); } } ././@LongLink0100644 0000000 0000000 00000000155 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestBasicClientCookie2.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestBasicClientCook0100644 0000000 0000000 00000012045 12301751655 032445 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.junit.Assert; import org.junit.Test; /** * Unit tests for {@link BasicClientCookie2}. */ public class TestBasicClientCookie2 { @Test public void testConstructor() { final BasicClientCookie2 cookie = new BasicClientCookie2("name", "value"); Assert.assertEquals("name", cookie.getName()); Assert.assertEquals("value", cookie.getValue()); try { new BasicClientCookie2(null, null); Assert.fail("IllegalArgumentException should have been thrown"); } catch (final IllegalArgumentException ex) { //expected } } @Test public void testCloning() throws Exception { final BasicClientCookie2 orig = new BasicClientCookie2("name", "value"); orig.setDomain("domain"); orig.setPath("/"); orig.setAttribute("attrib", "stuff"); orig.setPorts(new int[] {80, 8080}); final BasicClientCookie2 clone = (BasicClientCookie2) orig.clone(); Assert.assertEquals(orig.getName(), clone.getName()); Assert.assertEquals(orig.getValue(), clone.getValue()); Assert.assertEquals(orig.getDomain(), clone.getDomain()); Assert.assertEquals(orig.getPath(), clone.getPath()); Assert.assertEquals(orig.getAttribute("attrib"), clone.getAttribute("attrib")); Assert.assertEquals(orig.getPorts().length, clone.getPorts().length); Assert.assertEquals(orig.getPorts()[0], clone.getPorts()[0]); Assert.assertEquals(orig.getPorts()[1], clone.getPorts()[1]); } @Test public void testHTTPCLIENT_1031() throws Exception { final BasicClientCookie2 orig = new BasicClientCookie2("name", "value"); orig.setDomain("domain"); orig.setPath("/"); orig.setAttribute("attrib", "stuff"); final BasicClientCookie2 clone = (BasicClientCookie2) orig.clone(); Assert.assertEquals(orig.getName(), clone.getName()); Assert.assertEquals(orig.getValue(), clone.getValue()); Assert.assertEquals(orig.getDomain(), clone.getDomain()); Assert.assertEquals(orig.getPath(), clone.getPath()); Assert.assertEquals(orig.getAttribute("attrib"), clone.getAttribute("attrib")); Assert.assertNull(clone.getPorts()); } @Test public void testSerialization() throws Exception { final BasicClientCookie2 orig = new BasicClientCookie2("name", "value"); orig.setDomain("domain"); orig.setPath("/"); orig.setAttribute("attrib", "stuff"); orig.setPorts(new int[] {80, 8080}); final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream(); final ObjectOutputStream outstream = new ObjectOutputStream(outbuffer); outstream.writeObject(orig); outstream.close(); final byte[] raw = outbuffer.toByteArray(); final ByteArrayInputStream inbuffer = new ByteArrayInputStream(raw); final ObjectInputStream instream = new ObjectInputStream(inbuffer); final BasicClientCookie2 clone = (BasicClientCookie2) instream.readObject(); Assert.assertEquals(orig.getName(), clone.getName()); Assert.assertEquals(orig.getValue(), clone.getValue()); Assert.assertEquals(orig.getDomain(), clone.getDomain()); Assert.assertEquals(orig.getPath(), clone.getPath()); Assert.assertEquals(orig.getAttribute("attrib"), clone.getAttribute("attrib")); final int[] expected = orig.getPorts(); final int[] clones = clone.getPorts(); Assert.assertNotNull(expected); Assert.assertNotNull(clones); Assert.assertEquals(expected.length, clones.length); for (int i = 0; i < expected.length; i++) { Assert.assertEquals(expected[i], clones[i]); } } } ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestBasicCookieAttribHandlers.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestBasicCookieAttr0100644 0000000 0000000 00000045221 12301751655 032461 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.Locale; import org.apache.http.client.utils.DateUtils; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; import org.junit.Assert; import org.junit.Test; public class TestBasicCookieAttribHandlers { @Test public void testBasicDomainParse() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new BasicDomainHandler(); h.parse(cookie, "www.somedomain.com"); Assert.assertEquals("www.somedomain.com", cookie.getDomain()); } @Test(expected=MalformedCookieException.class) public void testBasicDomainParseInvalid1() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new BasicDomainHandler(); h.parse(cookie, ""); } @Test(expected=MalformedCookieException.class) public void testBasicDomainParseInvalid2() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new BasicDomainHandler(); h.parse(cookie, null); } @Test public void testBasicDomainValidate1() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("www.somedomain.com", 80, "/", false); final CookieAttributeHandler h = new BasicDomainHandler(); cookie.setDomain(".somedomain.com"); h.validate(cookie, origin); cookie.setDomain(".otherdomain.com"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } cookie.setDomain("www.otherdomain.com"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testBasicDomainValidate2() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somehost", 80, "/", false); final CookieAttributeHandler h = new BasicDomainHandler(); cookie.setDomain("somehost"); h.validate(cookie, origin); cookie.setDomain("otherhost"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testBasicDomainValidate3() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somedomain.com", 80, "/", false); final CookieAttributeHandler h = new BasicDomainHandler(); cookie.setDomain(".somedomain.com"); h.validate(cookie, origin); } @Test public void testBasicDomainValidate4() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somedomain.com", 80, "/", false); final CookieAttributeHandler h = new BasicDomainHandler(); cookie.setDomain(null); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testBasicDomainMatch1() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somedomain.com", 80, "/", false); final CookieAttributeHandler h = new BasicDomainHandler(); cookie.setDomain("somedomain.com"); Assert.assertTrue(h.match(cookie, origin)); cookie.setDomain(".somedomain.com"); Assert.assertTrue(h.match(cookie, origin)); } @Test public void testBasicDomainMatch2() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("www.somedomain.com", 80, "/", false); final CookieAttributeHandler h = new BasicDomainHandler(); cookie.setDomain("somedomain.com"); Assert.assertTrue(h.match(cookie, origin)); cookie.setDomain(".somedomain.com"); Assert.assertTrue(h.match(cookie, origin)); cookie.setDomain(null); Assert.assertFalse(h.match(cookie, origin)); } @Test public void testBasicDomainInvalidInput() throws Exception { final CookieAttributeHandler h = new BasicDomainHandler(); try { h.parse(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { h.validate(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { h.validate(new BasicClientCookie("name", "value"), null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { h.match(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { h.match(new BasicClientCookie("name", "value"), null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } } @Test public void testBasicPathParse() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new BasicPathHandler(); h.parse(cookie, "stuff"); Assert.assertEquals("stuff", cookie.getPath()); h.parse(cookie, ""); Assert.assertEquals("/", cookie.getPath()); h.parse(cookie, null); Assert.assertEquals("/", cookie.getPath()); } @Test public void testBasicPathMatch1() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somehost", 80, "/stuff", false); final CookieAttributeHandler h = new BasicPathHandler(); cookie.setPath("/stuff"); Assert.assertTrue(h.match(cookie, origin)); } @Test public void testBasicPathMatch2() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somehost", 80, "/stuff/", false); final CookieAttributeHandler h = new BasicPathHandler(); cookie.setPath("/stuff"); Assert.assertTrue(h.match(cookie, origin)); } @Test public void testBasicPathMatch3() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somehost", 80, "/stuff/more-stuff", false); final CookieAttributeHandler h = new BasicPathHandler(); cookie.setPath("/stuff"); Assert.assertTrue(h.match(cookie, origin)); } @Test public void testBasicPathMatch4() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somehost", 80, "/stuffed", false); final CookieAttributeHandler h = new BasicPathHandler(); cookie.setPath("/stuff"); Assert.assertFalse(h.match(cookie, origin)); } @Test public void testBasicPathMatch5() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somehost", 80, "/otherstuff", false); final CookieAttributeHandler h = new BasicPathHandler(); cookie.setPath("/stuff"); Assert.assertFalse(h.match(cookie, origin)); } @Test public void testBasicPathMatch6() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somehost", 80, "/stuff", false); final CookieAttributeHandler h = new BasicPathHandler(); cookie.setPath("/stuff/"); Assert.assertTrue(h.match(cookie, origin)); } @Test public void testBasicPathMatch7() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somehost", 80, "/stuff", false); final CookieAttributeHandler h = new BasicPathHandler(); Assert.assertTrue(h.match(cookie, origin)); } @Test public void testBasicPathValidate() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somehost", 80, "/stuff", false); final CookieAttributeHandler h = new BasicPathHandler(); cookie.setPath("/stuff"); h.validate(cookie, origin); cookie.setPath("/stuffed"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException must have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testBasicPathInvalidInput() throws Exception { final CookieAttributeHandler h = new BasicPathHandler(); try { h.parse(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { h.match(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { h.match(new BasicClientCookie("name", "value"), null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } } @Test public void testBasicMaxAgeParse() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new BasicMaxAgeHandler(); h.parse(cookie, "2000"); Assert.assertNotNull(cookie.getExpiryDate()); } @Test public void testBasicMaxAgeParseInvalid() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new BasicMaxAgeHandler(); try { h.parse(cookie, "garbage"); Assert.fail("MalformedCookieException must have been thrown"); } catch (final MalformedCookieException ex) { // expected } try { h.parse(cookie, null); Assert.fail("MalformedCookieException must have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testBasicMaxAgeInvalidInput() throws Exception { final CookieAttributeHandler h = new BasicMaxAgeHandler(); try { h.parse(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } } @Test public void testBasicCommentParse() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new BasicCommentHandler(); h.parse(cookie, "whatever"); Assert.assertEquals("whatever", cookie.getComment()); h.parse(cookie, null); Assert.assertEquals(null, cookie.getComment()); } @Test public void testBasicCommentInvalidInput() throws Exception { final CookieAttributeHandler h = new BasicCommentHandler(); try { h.parse(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } } @Test public void testBasicSecureParse() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new BasicSecureHandler(); h.parse(cookie, "whatever"); Assert.assertTrue(cookie.isSecure()); h.parse(cookie, null); Assert.assertTrue(cookie.isSecure()); } @Test public void testBasicSecureMatch() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new BasicSecureHandler(); final CookieOrigin origin1 = new CookieOrigin("somehost", 80, "/stuff", false); cookie.setSecure(false); Assert.assertTrue(h.match(cookie, origin1)); cookie.setSecure(true); Assert.assertFalse(h.match(cookie, origin1)); final CookieOrigin origin2 = new CookieOrigin("somehost", 80, "/stuff", true); cookie.setSecure(false); Assert.assertTrue(h.match(cookie, origin2)); cookie.setSecure(true); Assert.assertTrue(h.match(cookie, origin2)); } @Test public void testBasicSecureInvalidInput() throws Exception { final CookieAttributeHandler h = new BasicSecureHandler(); try { h.parse(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { h.match(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { h.match(new BasicClientCookie("name", "value"), null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } } @Test public void testBasicExpiresParse() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new BasicExpiresHandler(new String[] {DateUtils.PATTERN_RFC1123}); final DateFormat dateformat = new SimpleDateFormat(DateUtils.PATTERN_RFC1123, Locale.US); dateformat.setTimeZone(DateUtils.GMT); final Date now = new Date(); h.parse(cookie, dateformat.format(now)); Assert.assertNotNull(cookie.getExpiryDate()); } @Test public void testBasicExpiresParseInvalid() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new BasicExpiresHandler(new String[] {DateUtils.PATTERN_RFC1123}); try { h.parse(cookie, "garbage"); Assert.fail("MalformedCookieException must have been thrown"); } catch (final MalformedCookieException ex) { // expected } try { h.parse(cookie, null); Assert.fail("MalformedCookieException must have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testBasicExpiresInvalidInput() throws Exception { try { new BasicExpiresHandler(null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } final CookieAttributeHandler h = new BasicExpiresHandler(new String[] {DateUtils.PATTERN_RFC1123}); try { h.parse(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } } @Test public void testPublicSuffixFilter() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final PublicSuffixFilter h = new PublicSuffixFilter(new RFC2109DomainHandler()); h.setPublicSuffixes(Arrays.asList(new String[] { "co.uk", "com" })); cookie.setDomain(".co.uk"); Assert.assertFalse(h.match(cookie, new CookieOrigin("apache.co.uk", 80, "/stuff", false))); cookie.setDomain("co.uk"); Assert.assertFalse(h.match(cookie, new CookieOrigin("apache.co.uk", 80, "/stuff", false))); cookie.setDomain(".com"); Assert.assertFalse(h.match(cookie, new CookieOrigin("apache.com", 80, "/stuff", false))); cookie.setDomain("com"); Assert.assertFalse(h.match(cookie, new CookieOrigin("apache.com", 80, "/stuff", false))); cookie.setDomain("localhost"); Assert.assertTrue(h.match(cookie, new CookieOrigin("localhost", 80, "/stuff", false))); } } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestBrowserCompatSpec.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestBrowserCompatSp0100644 0000000 0000000 00000136766 12301751655 032564 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.http.Header; import org.apache.http.client.utils.DateUtils; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.message.BasicHeader; import org.junit.Assert; import org.junit.Test; /** * Test cases for BrowserCompatSpec * */ public class TestBrowserCompatSpec { @Test public void testConstructor() throws Exception { new BrowserCompatSpec(); new BrowserCompatSpec(null); new BrowserCompatSpec(new String[] { DateUtils.PATTERN_RFC1036 }); } /** * Tests whether domain attribute check is case-insensitive. */ @Test public void testDomainCaseInsensitivity() throws Exception { final Header header = new BasicHeader("Set-Cookie", "name=value; path=/; domain=.whatever.com"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("www.WhatEver.com", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); Assert.assertEquals(".whatever.com", cookies.get(0).getDomain()); } /** * Test basic parse (with various spacings */ @Test public void testParse1() throws Exception { final String headerValue = "custno = 12345; comment=test; version=1," + " name=John; version=1; max-age=600; secure; domain=.apache.org"; final Header header = new BasicHeader("set-cookie", headerValue); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("www.apache.org", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals(2, cookies.size()); Assert.assertEquals("custno", cookies.get(0).getName()); Assert.assertEquals("12345", cookies.get(0).getValue()); Assert.assertEquals("test", cookies.get(0).getComment()); Assert.assertEquals(1, cookies.get(0).getVersion()); Assert.assertEquals("www.apache.org", cookies.get(0).getDomain()); Assert.assertEquals("/", cookies.get(0).getPath()); Assert.assertFalse(cookies.get(0).isSecure()); Assert.assertEquals("name", cookies.get(1).getName()); Assert.assertEquals("John", cookies.get(1).getValue()); Assert.assertEquals(null, cookies.get(1).getComment()); Assert.assertEquals(1, cookies.get(1).getVersion()); Assert.assertEquals(".apache.org", cookies.get(1).getDomain()); Assert.assertEquals("/", cookies.get(1).getPath()); Assert.assertTrue(cookies.get(1).isSecure()); } /** * Test no spaces */ @Test public void testParse2() throws Exception { final String headerValue = "custno=12345;comment=test; version=1," + "name=John;version=1;max-age=600;secure;domain=.apache.org"; final Header header = new BasicHeader("set-cookie", headerValue); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("www.apache.org", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals(2, cookies.size()); Assert.assertEquals("custno", cookies.get(0).getName()); Assert.assertEquals("12345", cookies.get(0).getValue()); Assert.assertEquals("test", cookies.get(0).getComment()); Assert.assertEquals(1, cookies.get(0).getVersion()); Assert.assertEquals("www.apache.org", cookies.get(0).getDomain()); Assert.assertEquals("/", cookies.get(0).getPath()); Assert.assertFalse(cookies.get(0).isSecure()); Assert.assertEquals("name", cookies.get(1).getName()); Assert.assertEquals("John", cookies.get(1).getValue()); Assert.assertEquals(null, cookies.get(1).getComment()); Assert.assertEquals(1, cookies.get(1).getVersion()); Assert.assertEquals(".apache.org", cookies.get(1).getDomain()); Assert.assertEquals("/", cookies.get(1).getPath()); Assert.assertTrue(cookies.get(1).isSecure()); } /** * Test parse with quoted text */ @Test public void testParse3() throws Exception { final String headerValue = "name=\"Doe, John\";version=1;max-age=600;secure;domain=.apache.org"; final Header header = new BasicHeader("set-cookie", headerValue); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("www.apache.org", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals(1, cookies.size()); Assert.assertEquals("name", cookies.get(0).getName()); Assert.assertEquals("Doe, John", cookies.get(0).getValue()); Assert.assertEquals(null, cookies.get(0).getComment()); Assert.assertEquals(1, cookies.get(0).getVersion()); Assert.assertEquals(".apache.org", cookies.get(0).getDomain()); Assert.assertEquals("/", cookies.get(0).getPath()); Assert.assertTrue(cookies.get(0).isSecure()); } // see issue #5279 @Test public void testQuotedExpiresAttribute() throws Exception { final String headerValue = "custno=12345;Expires='Thu, 01-Jan-2070 00:00:10 GMT'"; final Header header = new BasicHeader("set-cookie", headerValue); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("www.apache.org", 80, "/", true); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull("Expected some cookies",cookies); Assert.assertEquals("Expected 1 cookie",1,cookies.size()); Assert.assertNotNull("Expected cookie to have getExpiryDate",cookies.get(0).getExpiryDate()); } @Test public void testSecurityError() throws Exception { final String headerValue = "custno=12345;comment=test; version=1," + "name=John;version=1;max-age=600;secure;domain=jakarta.apache.org"; final Header header = new BasicHeader("set-cookie", headerValue); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("www.apache.org", 80, "/", true); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException exception should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testParseSimple() throws Exception { final Header header = new BasicHeader("Set-Cookie","cookie-name=cookie-value"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/path/path", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookie.",1,cookies.size()); Assert.assertEquals("Name","cookie-name",cookies.get(0).getName()); Assert.assertEquals("Value","cookie-value",cookies.get(0).getValue()); Assert.assertTrue("Comment",null == cookies.get(0).getComment()); Assert.assertTrue("ExpiryDate",null == cookies.get(0).getExpiryDate()); //Assert.assertTrue("isToBeDiscarded",cookies.get(0).isToBeDiscarded()); Assert.assertTrue("isPersistent",!cookies.get(0).isPersistent()); Assert.assertEquals("Domain","127.0.0.1",cookies.get(0).getDomain()); Assert.assertEquals("Path","/path",cookies.get(0).getPath()); Assert.assertTrue("Secure",!cookies.get(0).isSecure()); Assert.assertEquals("Version",0,cookies.get(0).getVersion()); } @Test public void testParseSimple2() throws Exception { final Header header = new BasicHeader("Set-Cookie", "cookie-name=cookie-value"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/path", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookie.", 1, cookies.size()); Assert.assertEquals("Name", "cookie-name", cookies.get(0).getName()); Assert.assertEquals("Value", "cookie-value", cookies.get(0).getValue()); Assert.assertTrue("Comment", null == cookies.get(0).getComment()); Assert.assertTrue("ExpiryDate", null == cookies.get(0).getExpiryDate()); //Assert.assertTrue("isToBeDiscarded",cookies.get(0).isToBeDiscarded()); Assert.assertTrue("isPersistent", !cookies.get(0).isPersistent()); Assert.assertEquals("Domain", "127.0.0.1", cookies.get(0).getDomain()); Assert.assertEquals("Path", "/", cookies.get(0).getPath()); Assert.assertTrue("Secure", !cookies.get(0).isSecure()); Assert.assertEquals("Version", 0, cookies.get(0).getVersion()); } @Test public void testParseNoName() throws Exception { final Header header = new BasicHeader("Set-Cookie","=stuff; path=/"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", false); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testParseNoValue() throws Exception { final Header header = new BasicHeader("Set-Cookie","cookie-name="); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookie.",1,cookies.size()); Assert.assertEquals("Name","cookie-name",cookies.get(0).getName()); Assert.assertEquals("Value", "", cookies.get(0).getValue()); Assert.assertTrue("Comment",null == cookies.get(0).getComment()); Assert.assertTrue("ExpiryDate",null == cookies.get(0).getExpiryDate()); //Assert.assertTrue("isToBeDiscarded",cookies.get(0).isToBeDiscarded()); Assert.assertTrue("isPersistent",!cookies.get(0).isPersistent()); Assert.assertEquals("Domain","127.0.0.1",cookies.get(0).getDomain()); Assert.assertEquals("Path","/",cookies.get(0).getPath()); Assert.assertTrue("Secure",!cookies.get(0).isSecure()); Assert.assertEquals("Version",0,cookies.get(0).getVersion()); } @Test public void testParseWithWhiteSpace() throws Exception { final Header header = new BasicHeader("Set-Cookie"," cookie-name = cookie-value "); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookie.",1,cookies.size()); Assert.assertEquals("Name","cookie-name",cookies.get(0).getName()); Assert.assertEquals("Value","cookie-value",cookies.get(0).getValue()); Assert.assertEquals("Domain","127.0.0.1",cookies.get(0).getDomain()); Assert.assertEquals("Path","/",cookies.get(0).getPath()); Assert.assertTrue("Secure",!cookies.get(0).isSecure()); Assert.assertTrue("ExpiryDate",null == cookies.get(0).getExpiryDate()); Assert.assertTrue("Comment",null == cookies.get(0).getComment()); } @Test public void testParseWithQuotes() throws Exception { final Header header = new BasicHeader("Set-Cookie"," cookie-name = \" cookie-value \" ;path=/"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1",80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookie.",1,cookies.size()); Assert.assertEquals("Name","cookie-name",cookies.get(0).getName()); Assert.assertEquals("Value","\" cookie-value \"",cookies.get(0).getValue()); Assert.assertEquals("Domain","127.0.0.1",cookies.get(0).getDomain()); Assert.assertEquals("Path","/",cookies.get(0).getPath()); Assert.assertTrue("Secure",!cookies.get(0).isSecure()); Assert.assertTrue("ExpiryDate",null == cookies.get(0).getExpiryDate()); Assert.assertTrue("Comment",null == cookies.get(0).getComment()); } @Test public void testParseWithPath() throws Exception { final Header header = new BasicHeader("Set-Cookie","cookie-name=cookie-value; Path=/path/"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/path/path", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookie.",1,cookies.size()); Assert.assertEquals("Name","cookie-name",cookies.get(0).getName()); Assert.assertEquals("Value","cookie-value",cookies.get(0).getValue()); Assert.assertEquals("Domain","127.0.0.1",cookies.get(0).getDomain()); Assert.assertEquals("Path","/path/",cookies.get(0).getPath()); Assert.assertTrue("Secure",!cookies.get(0).isSecure()); Assert.assertTrue("ExpiryDate",null == cookies.get(0).getExpiryDate()); Assert.assertTrue("Comment",null == cookies.get(0).getComment()); } @Test public void testParseWithDomain() throws Exception { final Header header = new BasicHeader("Set-Cookie","cookie-name=cookie-value; Domain=127.0.0.1"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookie.",1,cookies.size()); Assert.assertEquals("Name","cookie-name",cookies.get(0).getName()); Assert.assertEquals("Value","cookie-value",cookies.get(0).getValue()); Assert.assertEquals("Domain","127.0.0.1",cookies.get(0).getDomain()); Assert.assertEquals("Path","/",cookies.get(0).getPath()); Assert.assertTrue("Secure",!cookies.get(0).isSecure()); Assert.assertTrue("ExpiryDate",null == cookies.get(0).getExpiryDate()); Assert.assertTrue("Comment",null == cookies.get(0).getComment()); } @Test public void testParseWithSecure() throws Exception { final Header header = new BasicHeader("Set-Cookie","cookie-name=cookie-value; secure"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", true); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookie.",1,cookies.size()); Assert.assertEquals("Name","cookie-name",cookies.get(0).getName()); Assert.assertEquals("Value","cookie-value",cookies.get(0).getValue()); Assert.assertEquals("Domain","127.0.0.1",cookies.get(0).getDomain()); Assert.assertEquals("Path","/",cookies.get(0).getPath()); Assert.assertTrue("Secure",cookies.get(0).isSecure()); Assert.assertTrue("ExpiryDate",null == cookies.get(0).getExpiryDate()); Assert.assertTrue("Comment",null == cookies.get(0).getComment()); } @Test public void testParseWithComment() throws Exception { final Header header = new BasicHeader("Set-Cookie", "cookie-name=cookie-value; comment=\"This is a comment.\""); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", true); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookie.",1,cookies.size()); Assert.assertEquals("Name","cookie-name",cookies.get(0).getName()); Assert.assertEquals("Value","cookie-value",cookies.get(0).getValue()); Assert.assertEquals("Domain","127.0.0.1",cookies.get(0).getDomain()); Assert.assertEquals("Path","/",cookies.get(0).getPath()); Assert.assertTrue("Secure",!cookies.get(0).isSecure()); Assert.assertTrue("ExpiryDate",null == cookies.get(0).getExpiryDate()); Assert.assertEquals("Comment","\"This is a comment.\"",cookies.get(0).getComment()); } @Test public void testParseWithExpires() throws Exception { final Header header = new BasicHeader("Set-Cookie", "cookie-name=cookie-value;Expires=Thu, 01-Jan-1970 00:00:10 GMT"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", true); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookie.",1,cookies.size()); Assert.assertEquals("Name","cookie-name",cookies.get(0).getName()); Assert.assertEquals("Value","cookie-value",cookies.get(0).getValue()); Assert.assertEquals("Domain","127.0.0.1",cookies.get(0).getDomain()); Assert.assertEquals("Path","/",cookies.get(0).getPath()); Assert.assertTrue("Secure",!cookies.get(0).isSecure()); Assert.assertEquals(new Date(10000L),cookies.get(0).getExpiryDate()); Assert.assertTrue("Comment",null == cookies.get(0).getComment()); } @Test public void testParseWithAll() throws Exception { final Header header = new BasicHeader("Set-Cookie", "cookie-name=cookie-value;Version=1;Path=/commons;Domain=.apache.org;" + "Comment=This is a comment.;secure;Expires=Thu, 01-Jan-1970 00:00:10 GMT"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("www.apache.org", 80, "/commons/httpclient", true); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookie.",1,cookies.size()); Assert.assertEquals("Name","cookie-name",cookies.get(0).getName()); Assert.assertEquals("Value","cookie-value",cookies.get(0).getValue()); Assert.assertEquals("Domain",".apache.org",cookies.get(0).getDomain()); Assert.assertEquals("Path","/commons",cookies.get(0).getPath()); Assert.assertTrue("Secure",cookies.get(0).isSecure()); Assert.assertEquals(new Date(10000L),cookies.get(0).getExpiryDate()); Assert.assertEquals("Comment","This is a comment.",cookies.get(0).getComment()); Assert.assertEquals("Version",1,cookies.get(0).getVersion()); } @Test public void testParseMultipleDifferentPaths() throws Exception { final Header header = new BasicHeader("Set-Cookie", "name1=value1;Version=1;Path=/commons,name1=value2;Version=1;" + "Path=/commons/httpclient;Version=1"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("www.apache.org", 80, "/commons/httpclient", true); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Wrong number of cookies.",2,cookies.size()); Assert.assertEquals("Name","name1",cookies.get(0).getName()); Assert.assertEquals("Value","value1",cookies.get(0).getValue()); Assert.assertEquals("Name","name1",cookies.get(1).getName()); Assert.assertEquals("Value","value2",cookies.get(1).getValue()); } @Test public void testParseRelativePath() throws Exception { final Header header = new BasicHeader("Set-Cookie", "name1=value1;Path=whatever"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("www.apache.org", 80, "whatever", true); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookies.",1,cookies.size()); Assert.assertEquals("Name","name1",cookies.get(0).getName()); Assert.assertEquals("Value","value1",cookies.get(0).getValue()); Assert.assertEquals("Path","whatever",cookies.get(0).getPath()); } @Test public void testParseWithWrongDomain() throws Exception { final Header header = new BasicHeader("Set-Cookie", "cookie-name=cookie-value; domain=127.0.0.1; version=1"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.2", 80, "/", false); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException exception should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testParseWithPathMismatch() throws Exception { final Header header = new BasicHeader("Set-Cookie", "cookie-name=cookie-value; path=/path/path/path"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/path", false); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException should have been thrown."); } catch (final MalformedCookieException e) { // expected } } @Test public void testParseWithPathMismatch2() throws Exception { final Header header = new BasicHeader("Set-Cookie", "cookie-name=cookie-value; path=/foobar"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/foo", false); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException should have been thrown."); } catch (final MalformedCookieException e) { // expected } } /** * Tests if cookie constructor rejects cookie name containing blanks. */ @Test public void testCookieNameWithBlanks() throws Exception { final Header header = new BasicHeader("Set-Cookie", "invalid name="); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); } /** * Tests if cookie constructor rejects cookie name containing blanks. */ @Test public void testCookieNameBlank() throws Exception { final Header header = new BasicHeader("Set-Cookie", "=stuff"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", false); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException expected) { } } /** * Tests if cookie constructor rejects cookie name starting with $. */ @Test public void testCookieNameStartingWithDollarSign() throws Exception { final Header header = new BasicHeader("Set-Cookie", "$invalid_name="); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); } /** * Tests if malformatted expires attribute is cookies correctly. */ @Test public void testCookieWithComma() throws Exception { final Header header = new BasicHeader("Set-Cookie", "name=value; expires=\"Thu, 01-Jan-1970 00:00:00 GMT"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("localhost", 80, "/", false); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException expected) { } } /** * Tests several date formats. */ @Test public void testDateFormats() throws Exception { //comma, dashes checkDate("Thu, 01-Jan-70 00:00:10 GMT"); checkDate("Thu, 01-Jan-2070 00:00:10 GMT"); //no comma, dashes checkDate("Thu 01-Jan-70 00:00:10 GMT"); checkDate("Thu 01-Jan-2070 00:00:10 GMT"); //comma, spaces checkDate("Thu, 01 Jan 70 00:00:10 GMT"); checkDate("Thu, 01 Jan 2070 00:00:10 GMT"); //no comma, spaces checkDate("Thu 01 Jan 70 00:00:10 GMT"); checkDate("Thu 01 Jan 2070 00:00:10 GMT"); //weird stuff checkDate("Wed, 20-Nov-2002 09-38-33 GMT"); try { checkDate("this aint a date"); Assert.fail("Date check is bogus"); } catch(final Exception e) { } } private void checkDate(final String date) throws Exception { final Header header = new BasicHeader("Set-Cookie", "custno=12345;Expires='"+date+"';"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("localhost", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } } /** * Tests if invalid second domain level cookie gets accepted in the * browser compatibility mode. */ @Test public void testSecondDomainLevelCookie() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", null); cookie.setDomain(".sourceforge.net"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain()); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("sourceforge.net", 80, "/", false); cookiespec.validate(cookie, origin); } @Test public void testSecondDomainLevelCookieMatch1() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", null); cookie.setDomain(".sourceforge.net"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain()); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("sourceforge.net", 80, "/", false); Assert.assertTrue(cookiespec.match(cookie, origin)); } @Test public void testSecondDomainLevelCookieMatch2() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", null); cookie.setDomain("sourceforge.net"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain()); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("www.sourceforge.net", 80, "/", false); Assert.assertTrue(cookiespec.match(cookie, origin)); } @Test public void testSecondDomainLevelCookieMatch3() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", null); cookie.setDomain(".sourceforge.net"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain()); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("www.sourceforge.net", 80, "/", false); Assert.assertTrue(cookiespec.match(cookie, origin)); } @Test public void testInvalidSecondDomainLevelCookieMatch1() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", null); cookie.setDomain(".sourceforge.net"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain()); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("antisourceforge.net", 80, "/", false); Assert.assertFalse(cookiespec.match(cookie, origin)); } @Test public void testInvalidSecondDomainLevelCookieMatch2() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", null); cookie.setDomain("sourceforge.net"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain()); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("antisourceforge.net", 80, "/", false); Assert.assertFalse(cookiespec.match(cookie, origin)); } @Test public void testMatchBlankPath() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain("host"); cookie.setPath("/"); final CookieOrigin origin = new CookieOrigin("host", 80, " ", false); Assert.assertTrue(cookiespec.match(cookie, origin)); } @Test public void testMatchNullCookieDomain() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setPath("/"); final CookieOrigin origin = new CookieOrigin("host", 80, "/", false); Assert.assertFalse(cookiespec.match(cookie, origin)); } @Test public void testMatchNullCookiePath() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain("host"); final CookieOrigin origin = new CookieOrigin("host", 80, "/", false); Assert.assertTrue(cookiespec.match(cookie, origin)); } @Test public void testCookieMatch1() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain("host"); cookie.setPath("/"); final CookieOrigin origin = new CookieOrigin("host", 80, "/", false); Assert.assertTrue(cookiespec.match(cookie, origin)); } @Test public void testCookieMatch2() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain(".whatever.com"); cookie.setPath("/"); final CookieOrigin origin = new CookieOrigin(".whatever.com", 80, "/", false); Assert.assertTrue(cookiespec.match(cookie, origin)); } @Test public void testCookieMatch3() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain(".whatever.com"); cookie.setPath("/"); final CookieOrigin origin = new CookieOrigin(".really.whatever.com", 80, "/", false); Assert.assertTrue(cookiespec.match(cookie, origin)); } @Test public void testCookieMatch4() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain("host"); cookie.setPath("/"); final CookieOrigin origin = new CookieOrigin("host", 80, "/foobar", false); Assert.assertTrue(cookiespec.match(cookie, origin)); } @Test public void testCookieMismatch1() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain("host1"); cookie.setPath("/"); final CookieOrigin origin = new CookieOrigin("host2", 80, "/", false); Assert.assertFalse(cookiespec.match(cookie, origin)); } @Test public void testCookieMismatch2() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain(".aaaaaaaaa.com"); cookie.setPath("/"); final CookieOrigin origin = new CookieOrigin(".bbbbbbbb.com", 80, "/", false); Assert.assertFalse(cookiespec.match(cookie, origin)); } @Test public void testCookieMismatch3() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain("host"); cookie.setPath("/foobar"); final CookieOrigin origin = new CookieOrigin("host", 80, "/foo", false); Assert.assertFalse(cookiespec.match(cookie, origin)); } @Test public void testCookieMismatch4() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain("host"); cookie.setPath("/foobar"); final CookieOrigin origin = new CookieOrigin("host", 80, "/foobar/", false); Assert.assertTrue(cookiespec.match(cookie, origin)); } @Test public void testCookieMatch5() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain("host"); cookie.setPath("/foobar/r"); final CookieOrigin origin = new CookieOrigin("host", 80, "/foobar/", false); Assert.assertFalse(cookiespec.match(cookie, origin)); } @Test public void testCookieMismatch6() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain("host"); cookie.setPath("/foobar"); cookie.setSecure(true); final CookieOrigin origin = new CookieOrigin("host", 80, "/foobar", false); Assert.assertFalse(cookiespec.match(cookie, origin)); } @Test public void testInvalidMatchDomain() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", null); cookie.setDomain("beta.gamma.com"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain()); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("alpha.beta.gamma.com", 80, "/", false); cookiespec.validate(cookie, origin); Assert.assertTrue(cookiespec.match(cookie, origin)); } /** * Tests generic cookie formatting. */ @Test public void testGenericCookieFormatting() throws Exception { final Header header = new BasicHeader("Set-Cookie", "name=value; path=/; domain=.mydomain.com"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false); final List cookies = cookiespec.parse(header, origin); cookiespec.validate(cookies.get(0), origin); final List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("name=value", headers.get(0).getValue()); } /** * Tests if null cookie values are handled correctly. */ @Test public void testNullCookieValueFormatting() { final BasicClientCookie cookie = new BasicClientCookie("name", null); cookie.setDomain(".whatever.com"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain()); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); final CookieSpec cookiespec = new BrowserCompatSpec(); final List cookies = new ArrayList(1); cookies.add(cookie); final List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("name=", headers.get(0).getValue()); } @Test public void testNullCookieValueFormattingCookieVersion1() { final BasicClientCookie cookie = new BasicClientCookie("name", null); cookie.setVersion(1); cookie.setDomain(".whatever.com"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain()); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); final CookieSpec cookiespec = new BrowserCompatSpec(); final List cookies = new ArrayList(1); cookies.add(cookie); final List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("name", headers.get(0).getValue()); } /** * Tests generic cookie formatting. */ @Test public void testFormatSeveralCookies() throws Exception { final Header header = new BasicHeader("Set-Cookie", "name1=value1; path=/; domain=.mydomain.com, name2 = value2 ; path=/; domain=.mydomain.com; version=0"); final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false); final List cookies = cookiespec.parse(header, origin); final List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("name1=value1; name2=value2", headers.get(0).getValue()); } @Test public void testKeepCloverHappy() throws Exception { new MalformedCookieException(); new MalformedCookieException("whatever"); new MalformedCookieException("whatever", null); } @Test public void testInvalidInput() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); try { cookiespec.parse(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { cookiespec.parse(new BasicHeader("Set-Cookie", "name=value"), null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { cookiespec.validate(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { cookiespec.validate(new BasicClientCookie("name", null), null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { cookiespec.match(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { cookiespec.match(new BasicClientCookie("name", null), null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { cookiespec.formatCookies(null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { final List cookies = new ArrayList(); cookiespec.formatCookies(cookies); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } } /** * Tests cookie version 1 with space in cookie value. */ @Test public void testFormatCookieWithSpaceInValue() throws Exception { final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false); final CookieSpec cookieSpec = new BrowserCompatSpec(); final Header setCookieHeader = new BasicHeader("Set-Cookie", "test=\"value 1\"; Version=1"); final Cookie cookie = cookieSpec.parse(setCookieHeader, origin).get(0); final List cookies = new ArrayList(); cookies.add(cookie); final List
headers = cookieSpec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("test=\"value 1\"", headers.get(0).getValue()); } /** * Tests Netscape cookie with space in cookie value. */ @Test public void testFormatCookieVersion0WithSpaceInValue() throws Exception { final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false); final CookieSpec cookieSpec = new BrowserCompatSpec(); final Header setCookieHeader = new BasicHeader("Set-Cookie", "test=value 1"); final Cookie cookie = cookieSpec.parse(setCookieHeader, origin).get(0); final List cookies = new ArrayList(); cookies.add(cookie); final List
headers = cookieSpec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("test=value 1", headers.get(0).getValue()); } @Test public void testVersion1CookieWithInvalidExpires() throws Exception { final CookieSpec cookiespec = new BrowserCompatSpec(); final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false); final Header origHeader = new BasicHeader("Set-Cookie", "test=\"test\"; Version=1; Expires=Mon, 11-Feb-2013 10:39:19 GMT; Path=/"); final List cookies = cookiespec.parse(origHeader, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); final Header header1 = headers.get(0); Assert.assertEquals("test=\"test\"", header1.getValue()); } } ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestCookieBestMatchSpec.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestCookieBestMatch0100644 0000000 0000000 00000026521 12301751655 032461 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.ArrayList; import java.util.List; import org.apache.http.Header; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.cookie.SetCookie2; import org.apache.http.message.BasicHeader; import org.junit.Assert; import org.junit.Test; /** * Test cases for 'best match' cookie policy */ public class TestCookieBestMatchSpec { @Test public void testCookieBrowserCompatParsing() throws Exception { final CookieSpec cookiespec = new BestMatchSpec(); final CookieOrigin origin = new CookieOrigin("a.b.domain.com", 80, "/", false); // Make sure the lenient (browser compatible) cookie parsing // and validation is used for Netscape style cookies final Header header = new BasicHeader("Set-Cookie", "name=value;path=/;domain=domain.com"); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } } @Test public void testNetscapeCookieParsing() throws Exception { final CookieSpec cookiespec = new BestMatchSpec(); final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false); Header header = new BasicHeader("Set-Cookie", "name=value; path=/; domain=.mydomain.com; expires=Thu, 01-Jan-2070 00:00:10 GMT; comment=no_comment"); List cookies = cookiespec.parse(header, origin); cookiespec.validate(cookies.get(0), origin); Assert.assertEquals(1, cookies.size()); header = new BasicHeader("Set-Cookie", "name=value; path=/; domain=.mydomain.com; expires=Thu, 01-Jan-2070 00:00:10 GMT; version=1"); cookies = cookiespec.parse(header, origin); cookiespec.validate(cookies.get(0), origin); Assert.assertEquals(1, cookies.size()); } @Test public void testCookieStandardCompliantParsing() throws Exception { final CookieSpec cookiespec = new BestMatchSpec(); final CookieOrigin origin = new CookieOrigin("a.b.domain.com", 80, "/", false); // Make sure the strict (RFC2965) cookie parsing // and validation is used for version 1 Set-Cookie2 headers Header header = new BasicHeader("Set-Cookie2", "name=value;path=/;domain=b.domain.com; version=1"); List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } // Make sure the strict (RFC2109) cookie parsing // and validation is used for version 1 Set-Cookie headers header = new BasicHeader("Set-Cookie", "name=value;path=/;domain=.b.domain.com; version=1"); cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } header = new BasicHeader("Set-Cookie2", "name=value;path=/;domain=domain.com; version=1"); try { cookies = cookiespec.parse(header, origin); cookiespec.validate(cookies.get(0), origin); Assert.fail("MalformedCookieException exception should have been thrown"); } catch (final MalformedCookieException e) { // expected } } @Test public void testCookieStandardCompliantParsingLocalHost() throws Exception { final CookieSpec cookiespec = new BestMatchSpec(); final CookieOrigin origin = new CookieOrigin("localhost", 80, "/", false); final Header header = new BasicHeader("Set-Cookie", "special=\"abcdigh\"; Version=1"); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { final Cookie cookie = cookies.get(i); cookiespec.validate(cookie, origin); Assert.assertEquals("localhost", cookie.getDomain()); Assert.assertFalse(cookie instanceof SetCookie2); } } @Test public void testCookieStandardCompliantParsingLocalHost2() throws Exception { final CookieSpec cookiespec = new BestMatchSpec(); final CookieOrigin origin = new CookieOrigin("localhost", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "special=\"abcdigh\"; Version=1"); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { final Cookie cookie = cookies.get(i); cookiespec.validate(cookie, origin); Assert.assertEquals("localhost.local", cookie.getDomain()); Assert.assertTrue(cookie instanceof SetCookie2); } } @Test public void testCookieBrowserCompatMatch() throws Exception { final CookieSpec cookiespec = new BestMatchSpec(); final CookieOrigin origin = new CookieOrigin("a.b.domain.com", 80, "/", false); // Make sure the lenient (browser compatible) cookie matching // is used for Netscape style cookies final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain(".domain.com"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain()); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); Assert.assertTrue(cookiespec.match(cookie, origin)); } @Test public void testCookieStandardCompliantMatch() throws Exception { final CookieSpec cookiespec = new BestMatchSpec(); final CookieOrigin origin = new CookieOrigin("a.b.domain.com", 80, "/", false); // Make sure the strict (RFC2965) cookie matching // is used for version 1 cookies final BasicClientCookie2 cookie = new BasicClientCookie2("name", "value"); cookie.setVersion(1); cookie.setDomain(".domain.com"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain()); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); Assert.assertFalse(cookiespec.match(cookie, origin)); cookie.setDomain(".b.domain.com"); Assert.assertTrue(cookiespec.match(cookie, origin)); } @Test public void testCookieBrowserCompatFormatting() throws Exception { final CookieSpec cookiespec = new BestMatchSpec(); // Make sure the lenient (browser compatible) cookie formatting // is used for Netscape style cookies final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value1"); cookie1.setDomain(".domain.com"); cookie1.setAttribute(ClientCookie.DOMAIN_ATTR, cookie1.getDomain()); cookie1.setPath("/"); cookie1.setAttribute(ClientCookie.PATH_ATTR, cookie1.getPath()); final BasicClientCookie cookie2 = new BasicClientCookie("name2", "value2"); cookie2.setVersion(1); cookie2.setDomain(".domain.com"); cookie2.setAttribute(ClientCookie.DOMAIN_ATTR, cookie2.getDomain()); cookie2.setPath("/"); cookie2.setAttribute(ClientCookie.PATH_ATTR, cookie2.getPath()); final List cookies = new ArrayList(); cookies.add(cookie1); cookies.add(cookie2); final List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); final Header header = headers.get(0); Assert.assertEquals("name1=value1; name2=value2", header.getValue()); } @Test public void testCookieStandardCompliantFormatting() throws Exception { final CookieSpec cookiespec = new BestMatchSpec(null, true); // Make sure the strict (RFC2965) cookie formatting // is used for Netscape style cookies final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value1"); cookie1.setVersion(1); cookie1.setDomain(".domain.com"); cookie1.setAttribute(ClientCookie.DOMAIN_ATTR, cookie1.getDomain()); cookie1.setPath("/"); cookie1.setAttribute(ClientCookie.PATH_ATTR, cookie1.getPath()); final BasicClientCookie cookie2 = new BasicClientCookie("name2", "value2"); cookie2.setVersion(1); cookie2.setDomain(".domain.com"); cookie2.setAttribute(ClientCookie.DOMAIN_ATTR, cookie2.getDomain()); cookie2.setPath("/"); cookie2.setAttribute(ClientCookie.PATH_ATTR, cookie2.getPath()); final List cookies = new ArrayList(); cookies.add(cookie1); cookies.add(cookie2); final List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); final Header header = headers.get(0); Assert.assertEquals("$Version=1; name1=\"value1\"; $Path=\"/\"; $Domain=\".domain.com\"; " + "name2=\"value2\"; $Path=\"/\"; $Domain=\".domain.com\"", header.getValue()); } @Test public void testInvalidInput() throws Exception { final CookieSpec cookiespec = new BestMatchSpec(); try { cookiespec.parse(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { cookiespec.parse(new BasicHeader("Set-Cookie", "name=value"), null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { cookiespec.formatCookies(null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { final List cookies = new ArrayList(); cookiespec.formatCookies(cookies); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } } } ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestCookieNetscapeDraft.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestCookieNetscapeD0100644 0000000 0000000 00000030555 12301751655 032457 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.TimeZone; import org.apache.http.Header; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.message.BasicHeader; import org.junit.Assert; import org.junit.Test; /** * Test cases for Netscape cookie draft */ public class TestCookieNetscapeDraft { @Test public void testParseAbsPath() throws Exception { final Header header = new BasicHeader("Set-Cookie", "name1=value1;Path=/path/"); final CookieSpec cookiespec = new NetscapeDraftSpec(); final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookies.",1,cookies.size()); Assert.assertEquals("Name","name1",cookies.get(0).getName()); Assert.assertEquals("Value","value1",cookies.get(0).getValue()); Assert.assertEquals("Domain","host",cookies.get(0).getDomain()); Assert.assertEquals("Path","/path/",cookies.get(0).getPath()); } @Test public void testParseAbsPath2() throws Exception { final Header header = new BasicHeader("Set-Cookie", "name1=value1;Path=/"); final CookieSpec cookiespec = new NetscapeDraftSpec(); final CookieOrigin origin = new CookieOrigin("host", 80, "/", true); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookies.",1,cookies.size()); Assert.assertEquals("Name","name1",cookies.get(0).getName()); Assert.assertEquals("Value","value1",cookies.get(0).getValue()); Assert.assertEquals("Domain","host",cookies.get(0).getDomain()); Assert.assertEquals("Path","/",cookies.get(0).getPath()); } @Test public void testParseRelativePath() throws Exception { final Header header = new BasicHeader("Set-Cookie", "name1=value1;Path=whatever"); final CookieSpec cookiespec = new NetscapeDraftSpec(); final CookieOrigin origin = new CookieOrigin("host", 80, "whatever", true); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookies.",1,cookies.size()); Assert.assertEquals("Name","name1",cookies.get(0).getName()); Assert.assertEquals("Value","value1",cookies.get(0).getValue()); Assert.assertEquals("Domain","host",cookies.get(0).getDomain()); Assert.assertEquals("Path","whatever",cookies.get(0).getPath()); } @Test public void testParseWithIllegalNetscapeDomain1() throws Exception { final Header header = new BasicHeader("Set-Cookie","cookie-name=cookie-value; domain=.com"); final CookieSpec cookiespec = new NetscapeDraftSpec(); try { final CookieOrigin origin = new CookieOrigin("a.com", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException exception should have been thrown"); } catch (final MalformedCookieException e) { // expected } } @Test public void testParseWithWrongNetscapeDomain2() throws Exception { final Header header = new BasicHeader("Set-Cookie","cookie-name=cookie-value; domain=.y.z"); final CookieSpec cookiespec = new NetscapeDraftSpec(); try { final CookieOrigin origin = new CookieOrigin("x.y.z", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException exception should have been thrown"); } catch (final MalformedCookieException e) { // expected } } /** * Tests Netscape specific cookie formatting. */ @Test public void testNetscapeCookieFormatting() throws Exception { final Header header = new BasicHeader( "Set-Cookie", "name=value; path=/; domain=.mydomain.com"); final CookieSpec cookiespec = new NetscapeDraftSpec(); final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false); final List cookies = cookiespec.parse(header, origin); cookiespec.validate(cookies.get(0), origin); final List
headers = cookiespec.formatCookies(cookies); Assert.assertEquals(1, headers.size()); Assert.assertEquals("name=value", headers.get(0).getValue()); } /** * Tests Netscape specific expire attribute parsing. */ @Test public void testNetscapeCookieExpireAttribute() throws Exception { final CookieSpec cookiespec = new NetscapeDraftSpec(); final Header header = new BasicHeader("Set-Cookie", "name=value; path=/; domain=.mydomain.com; expires=Thu, 01-Jan-2070 00:00:10 GMT; comment=no_comment"); final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false); final List cookies = cookiespec.parse(header, origin); cookiespec.validate(cookies.get(0), origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final Cookie cookie = cookies.get(0); final Calendar c = Calendar.getInstance(); c.setTimeZone(TimeZone.getTimeZone("GMT")); c.setTime(cookie.getExpiryDate()); final int year = c.get(Calendar.YEAR); Assert.assertEquals(2070, year); } /** * Expire attribute with two digit year. */ @Test public void testNetscapeCookieExpireAttributeTwoDigitYear() throws Exception { final CookieSpec cookiespec = new NetscapeDraftSpec(); final Header header = new BasicHeader("Set-Cookie", "name=value; path=/; domain=.mydomain.com; expires=Thursday, 01-Jan-70 00:00:10 GMT; comment=no_comment"); final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false); final List cookies = cookiespec.parse(header, origin); cookiespec.validate(cookies.get(0), origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final Cookie cookie = cookies.get(0); final Calendar c = Calendar.getInstance(); c.setTimeZone(TimeZone.getTimeZone("GMT")); c.setTime(cookie.getExpiryDate()); final int year = c.get(Calendar.YEAR); Assert.assertEquals(2070, year); } /** * Invalid expire attribute. */ @Test public void testNetscapeCookieInvalidExpireAttribute() throws Exception { final CookieSpec cookiespec = new NetscapeDraftSpec(); final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie", "name=value; path=/; domain=.mydomain.com; expires=Thu 01-Jan-2070 00:00:10 GMT; comment=no_comment"); try { final List cookies = cookiespec.parse(header, origin); cookiespec.validate(cookies.get(0), origin); Assert.fail("MalformedCookieException exception should have been thrown"); } catch (final MalformedCookieException e) { // expected } } /** * Tests Netscape specific expire attribute without a time zone. */ @Test public void testNetscapeCookieExpireAttributeNoTimeZone() throws Exception { final CookieSpec cookiespec = new NetscapeDraftSpec(); final Header header = new BasicHeader("Set-Cookie", "name=value; expires=Thu, 01-Jan-2006 00:00:00 "); final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false); try { cookiespec.parse(header, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } /** * Tests if cookie values with embedded comma are handled correctly. */ @Test public void testCookieWithComma() throws Exception { final Header header = new BasicHeader("Set-Cookie", "a=b,c"); final CookieSpec cookiespec = new NetscapeDraftSpec(); final CookieOrigin origin = new CookieOrigin("localhost", 80, "/", false); final List cookies = cookiespec.parse(header, origin); Assert.assertEquals("number of cookies", 1, cookies.size()); Assert.assertEquals("a", cookies.get(0).getName()); Assert.assertEquals("b,c", cookies.get(0).getValue()); } @Test public void testFormatCookies() throws Exception { final BasicClientCookie c1 = new BasicClientCookie("name1", "value1"); c1.setDomain(".whatever.com"); c1.setAttribute(ClientCookie.DOMAIN_ATTR, c1.getDomain()); c1.setPath("/"); c1.setAttribute(ClientCookie.PATH_ATTR, c1.getPath()); final Cookie c2 = new BasicClientCookie("name2", "value2"); final Cookie c3 = new BasicClientCookie("name3", null); final CookieSpec cookiespec = new NetscapeDraftSpec(); final List cookies = new ArrayList(); cookies.add(c1); cookies.add(c2); cookies.add(c3); final List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("name1=value1; name2=value2; name3", headers.get(0).getValue()); } @Test public void testInvalidInput() throws Exception { final CookieSpec cookiespec = new NetscapeDraftSpec(); try { cookiespec.parse(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { cookiespec.parse(new BasicHeader("Set-Cookie", "name=value"), null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { cookiespec.formatCookies(null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { final List cookies = new ArrayList(); cookiespec.formatCookies(cookies); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } } } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestCookieRFC2109Spec.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestCookieRFC2109Sp0100644 0000000 0000000 00000047700 12301751655 032042 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.ArrayList; import java.util.List; import org.apache.http.Header; import org.apache.http.client.utils.DateUtils; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.message.BasicHeader; import org.junit.Assert; import org.junit.Test; /** * Test cases for RFC2109 cookie spec */ public class TestCookieRFC2109Spec { @Test public void testConstructor() throws Exception { new RFC2109Spec(); new RFC2109Spec(null, false); new RFC2109Spec(new String[] { DateUtils.PATTERN_RFC1036 }, false); } @Test public void testParseVersion() throws Exception { final Header header = new BasicHeader("Set-Cookie","cookie-name=cookie-value; version=1"); final CookieSpec cookiespec = new RFC2109Spec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertEquals("Found 1 cookie.",1,cookies.size()); Assert.assertEquals("Name","cookie-name",cookies.get(0).getName()); Assert.assertEquals("Value","cookie-value",cookies.get(0).getValue()); Assert.assertEquals("Version",1,cookies.get(0).getVersion()); } /** * Test domain equals host */ @Test public void testCookiesomainEqualsHost() throws Exception { final Header header = new BasicHeader("Set-Cookie", "cookie-name=cookie-value; domain=www.b.com; version=1"); final CookieSpec cookiespec = new RFC2109Spec(); final CookieOrigin origin = new CookieOrigin("www.b.com", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); Assert.assertEquals("www.b.com", cookies.get(0).getDomain()); } /** * Domain does not start with a dot */ @Test public void testParseWithIllegalDomain1() throws Exception { final Header header = new BasicHeader("Set-Cookie", "cookie-name=cookie-value; domain=a.b.com; version=1"); final CookieSpec cookiespec = new RFC2109Spec(); final CookieOrigin origin = new CookieOrigin("www.a.b.com", 80, "/", false); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException e) { // expected } } /** * Domain must have alt least one embedded dot */ @Test public void testParseWithIllegalDomain2() throws Exception { final Header header = new BasicHeader("Set-Cookie", "cookie-name=cookie-value; domain=.com; version=1"); final CookieSpec cookiespec = new RFC2109Spec(); final CookieOrigin origin = new CookieOrigin("b.com", 80, "/", false); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException e) { // expected } } /** * Host minus domain may not contain any dots */ @Test public void testParseWithIllegalDomain4() throws Exception { final Header header = new BasicHeader("Set-Cookie", "cookie-name=cookie-value; domain=.c.com; version=1"); final CookieSpec cookiespec = new RFC2109Spec(); final CookieOrigin origin = new CookieOrigin("a.b.c.com", 80, "/", false); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException e) { // expected } } /** * Tests if that invalid second domain level cookie gets * rejected in the strict mode, but gets accepted in the * browser compatibility mode. */ @Test public void testSecondDomainLevelCookie() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", null); cookie.setDomain(".sourceforge.net"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain()); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); final CookieSpec cookiespec = new RFC2109Spec(); final CookieOrigin origin = new CookieOrigin("sourceforge.net", 80, "/", false); try { cookiespec.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException e) { // Expected } } @Test public void testSecondDomainLevelCookieMatch() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", null); cookie.setDomain(".sourceforge.net"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain()); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); final CookieSpec cookiespec = new RFC2109Spec(); final CookieOrigin origin = new CookieOrigin("sourceforge.net", 80, "/", false); Assert.assertFalse(cookiespec.match(cookie, origin)); } @Test public void testParseWithWrongPath() throws Exception { final Header header = new BasicHeader("Set-Cookie", "cookie-name=cookie-value; domain=127.0.0.1; path=/not/just/root"); final CookieSpec cookiespec = new RFC2109Spec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", false); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException exception should have been thrown"); } catch (final MalformedCookieException e) { // expected } } /** * Tests if cookie constructor rejects cookie name containing blanks. */ @Test public void testCookieNameWithBlanks() throws Exception { final Header setcookie = new BasicHeader("Set-Cookie", "invalid name="); final CookieSpec cookiespec = new RFC2109Spec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", false); try { final List cookies = cookiespec.parse(setcookie, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException exception should have been thrown"); } catch (final MalformedCookieException e) { // expected } } /** * Tests if cookie constructor rejects cookie name starting with $. */ @Test public void testCookieNameStartingWithDollarSign() throws Exception { final Header setcookie = new BasicHeader("Set-Cookie", "$invalid_name="); final CookieSpec cookiespec = new RFC2109Spec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", false); try { final List cookies = cookiespec.parse(setcookie, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException exception should have been thrown"); } catch (final MalformedCookieException e) { // expected } } /** * Tests if default cookie validator rejects cookies originating from a host without domain * where domain attribute does not match the host of origin */ @Test public void testInvalidDomainWithSimpleHostName() throws Exception { final CookieSpec cookiespec = new RFC2109Spec(); Header header = new BasicHeader("Set-Cookie", "name=\"value\"; version=\"1\"; path=\"/\"; domain=\".mydomain.com\""); final CookieOrigin origin1 = new CookieOrigin("host", 80, "/", false); List cookies = cookiespec.parse(header, origin1); try { cookiespec.validate(cookies.get(0), origin1); Assert.fail("MalformedCookieException must have thrown"); } catch(final MalformedCookieException expected) { } final CookieOrigin origin2 = new CookieOrigin("host2", 80, "/", false); header = new BasicHeader("Set-Cookie", "name=\"value\"; version=\"1\"; path=\"/\"; domain=\"host1\""); cookies = cookiespec.parse(header, origin2); try { cookiespec.validate(cookies.get(0), origin2); Assert.fail("MalformedCookieException must have thrown"); } catch(final MalformedCookieException expected) { } } /** * Tests if cookie values with embedded comma are handled correctly. */ @Test public void testCookieWithComma() throws Exception { final Header header = new BasicHeader("Set-Cookie", "a=b,c"); final CookieSpec cookiespec = new RFC2109Spec(); final CookieOrigin origin = new CookieOrigin("localhost", 80, "/", false); final List cookies = cookiespec.parse(header, origin); Assert.assertEquals("number of cookies", 2, cookies.size()); Assert.assertEquals("a", cookies.get(0).getName()); Assert.assertEquals("b", cookies.get(0).getValue()); Assert.assertEquals("c", cookies.get(1).getName()); Assert.assertEquals(null, cookies.get(1).getValue()); } /** * Tests RFC 2109 compiant cookie formatting. */ @Test public void testRFC2109CookieFormatting() throws Exception { final CookieSpec cookiespec = new RFC2109Spec(null, false); Header header = new BasicHeader("Set-Cookie", "name=\"value\"; version=1; path=\"/\"; domain=\".mydomain.com\""); final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false); List cookies = cookiespec.parse(header, origin); cookiespec.validate(cookies.get(0), origin); List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("$Version=1; name=\"value\"; $Path=\"/\"; $Domain=\".mydomain.com\"", headers.get(0).getValue()); header = new BasicHeader( "Set-Cookie", "name=value; path=/; domain=.mydomain.com"); cookies = cookiespec.parse(header, origin); cookiespec.validate(cookies.get(0), origin); headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("$Version=0; name=value; $Path=/; $Domain=.mydomain.com", headers.get(0).getValue()); } @Test public void testRFC2109CookiesFormatting() throws Exception { final CookieSpec cookiespec = new RFC2109Spec(null, true); Header header = new BasicHeader("Set-Cookie", "name1=value1; path=/; domain=.mydomain.com, " + "name2=\"value2\"; version=\"1\"; path=\"/\"; domain=\".mydomain.com\""); final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false); List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull(cookies); Assert.assertEquals(2, cookies.size()); List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals( "$Version=0; name1=value1; $Path=/; $Domain=.mydomain.com; " + "name2=value2; $Path=/; $Domain=.mydomain.com", headers.get(0).getValue()); header = new BasicHeader("Set-Cookie", "name1=value1; version=1; path=/; domain=.mydomain.com, " + "name2=\"value2\"; version=\"1\"; path=\"/\"; domain=\".mydomain.com\""); cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull(cookies); Assert.assertEquals(2, cookies.size()); headers = cookiespec.formatCookies(cookies); Assert.assertEquals( "$Version=1; name1=\"value1\"; $Path=\"/\"; $Domain=\".mydomain.com\"; " + "name2=\"value2\"; $Path=\"/\"; $Domain=\".mydomain.com\"", headers.get(0).getValue()); } /** * Tests if null cookie values are handled correctly. */ @Test public void testNullCookieValueFormatting() { final BasicClientCookie cookie = new BasicClientCookie("name", null); cookie.setDomain(".whatever.com"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain()); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); final CookieSpec cookiespec = new RFC2109Spec(); List cookies = new ArrayList(); cookies.add(cookie); List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("$Version=0; name=; $Path=/; $Domain=.whatever.com", headers.get(0).getValue()); cookie.setVersion(1); cookies = new ArrayList(); cookies.add(cookie); headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("$Version=1; name=; $Path=\"/\"; $Domain=\".whatever.com\"", headers.get(0).getValue()); } @Test public void testCookieNullDomainNullPathFormatting() { final BasicClientCookie cookie = new BasicClientCookie("name", null); cookie.setPath("/"); cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath()); final CookieSpec cookiespec = new RFC2109Spec(); List cookies = new ArrayList(); cookies.add(cookie); List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("$Version=0; name=; $Path=/", headers.get(0).getValue()); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, null); cookie.setAttribute(ClientCookie.PATH_ATTR, null); cookies = new ArrayList(); cookies.add(cookie); headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("$Version=0; name=", headers.get(0).getValue()); } @Test public void testCookieOrderingByPath() { final BasicClientCookie c1 = new BasicClientCookie("name1", "value1"); c1.setPath("/a/b/c"); c1.setAttribute(ClientCookie.PATH_ATTR, c1.getPath()); final BasicClientCookie c2 = new BasicClientCookie("name2", "value2"); c2.setPath("/a/b"); c2.setAttribute(ClientCookie.PATH_ATTR, c2.getPath()); final BasicClientCookie c3 = new BasicClientCookie("name3", "value3"); c3.setPath("/a"); c3.setAttribute(ClientCookie.PATH_ATTR, c3.getPath()); final BasicClientCookie c4 = new BasicClientCookie("name4", "value4"); c4.setPath("/"); c4.setAttribute(ClientCookie.PATH_ATTR, c4.getPath()); final CookieSpec cookiespec = new RFC2109Spec(null, true); final List cookies = new ArrayList(); cookies.add(c2); cookies.add(c4); cookies.add(c1); cookies.add(c3); final List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("$Version=0; name1=value1; $Path=/a/b/c; " + "name2=value2; $Path=/a/b; " + "name3=value3; $Path=/a; " + "name4=value4; $Path=/", headers.get(0).getValue()); } @Test(expected=MalformedCookieException.class) public void testVersion1CookieWithInvalidExpires() throws Exception { final CookieSpec cookiespec = new RFC2109Spec(); final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false); final Header origHeader = new BasicHeader("Set-Cookie", "test=\"test\"; Version=1; Expires=Mon, 11-Feb-2013 10:39:19 GMT; Path=/"); cookiespec.parse(origHeader, origin); } @Test public void testInvalidInput() throws Exception { final CookieSpec cookiespec = new RFC2109Spec(); try { cookiespec.parse(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { cookiespec.parse(new BasicHeader("Set-Cookie", "name=value"), null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { cookiespec.validate(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { cookiespec.formatCookies(null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { final List cookies = new ArrayList(); cookiespec.formatCookies(cookies); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } } } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestCookieRFC2965Spec.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestCookieRFC2965Sp0100644 0000000 0000000 00000131370 12301751655 032051 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.http.Header; import org.apache.http.cookie.ClientCookie; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.message.BasicHeader; import org.junit.Assert; import org.junit.Test; /** * Test cases for RFC2965 cookie spec */ public class TestCookieRFC2965Spec { /** * Test parsing cookie "Path" attribute. */ @Test public void testParsePath() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Path=/;Version=1;Path="); final List cookies = cookiespec.parse(header, origin); Assert .assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); // only the first occurrence of path attribute is considered, others ignored final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertEquals("/", cookie.getPath()); Assert.assertTrue(cookie.containsAttribute(ClientCookie.PATH_ATTR)); } @Test public void testParsePathDefault() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/path/", false); // Path is OPTIONAL, defaults to the request path final Header header = new BasicHeader("Set-Cookie2", "name=value;Version=1"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertEquals("/path", cookie.getPath()); Assert.assertFalse(cookie.containsAttribute(ClientCookie.PATH_ATTR)); } @Test public void testParseNullPath() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Path=;Version=1"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertEquals("/", cookie.getPath()); Assert.assertTrue(cookie.containsAttribute(ClientCookie.PATH_ATTR)); } @Test public void testParseBlankPath() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Path=\" \";Version=1"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertEquals("/", cookie.getPath()); Assert.assertTrue(cookie.containsAttribute(ClientCookie.PATH_ATTR)); } /** * Test parsing cookie "Domain" attribute. */ @Test public void testParseDomain() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); Header header = new BasicHeader("Set-Cookie2", "name=value;Domain=.domain.com;Version=1;Domain="); List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); // only the first occurrence of domain attribute is considered, others ignored ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertEquals(".domain.com", cookie.getDomain()); Assert.assertTrue(cookie.containsAttribute(ClientCookie.DOMAIN_ATTR)); // should put a leading dot if there is no dot in front of domain header = new BasicHeader("Set-Cookie2", "name=value;Domain=domain.com;Version=1"); cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); cookie = (ClientCookie) cookies.get(0); Assert.assertEquals(".domain.com", cookie.getDomain()); } @Test public void testParseDomainDefaultValue() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); // Domain is OPTIONAL, defaults to the request host final Header header = new BasicHeader("Set-Cookie2", "name=value;Version=1"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertEquals("www.domain.com", cookie.getDomain()); Assert.assertFalse(cookie.containsAttribute(ClientCookie.DOMAIN_ATTR)); } @Test public void testParseNullDomain() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); // domain cannot be null final Header header = new BasicHeader("Set-Cookie2", "name=value;Domain=;Version=1"); try { cookiespec.parse(header, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testParseBlankDomain() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Domain=\" \";Version=1"); try { cookiespec.parse(header, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } /** * Test parsing cookie "Port" attribute. */ @Test public void testParsePort() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Port=\"80,800,8000\";Version=1;Port=nonsense"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); // only the first occurrence of port attribute is considered, others ignored final ClientCookie cookie = (ClientCookie) cookies.get(0); final int[] ports = cookie.getPorts(); Assert.assertNotNull(ports); Assert.assertEquals(3, ports.length); Assert.assertEquals(80, ports[0]); Assert.assertEquals(800, ports[1]); Assert.assertEquals(8000, ports[2]); Assert.assertTrue(cookie.containsAttribute(ClientCookie.PORT_ATTR)); } @Test public void testParsePortDefault() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); // Port is OPTIONAL, cookie can be accepted from any port final Header header = new BasicHeader("Set-Cookie2", "name=value;Version=1"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertFalse(cookie.containsAttribute(ClientCookie.PORT_ATTR)); } @Test public void testParseNullPort() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); // null port defaults to request port final Header header = new BasicHeader("Set-Cookie2", "name=value;Port=;Version=1"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); final int[] ports = cookie.getPorts(); Assert.assertNotNull(ports); Assert.assertEquals(1, ports.length); Assert.assertEquals(80, ports[0]); Assert.assertEquals("", cookie.getAttribute(ClientCookie.PORT_ATTR)); } @Test public void testParseBlankPort() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); // blank port defaults to request port final Header header = new BasicHeader("Set-Cookie2", "name=value;Port=\" \";Version=1"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); final int[] ports = cookie.getPorts(); Assert.assertNotNull(ports); Assert.assertEquals(1, ports.length); Assert.assertEquals(80, ports[0]); Assert.assertEquals(" ", cookie.getAttribute(ClientCookie.PORT_ATTR)); } @Test public void testParseInvalidPort() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Port=nonsense;Version=1"); try { cookiespec.parse(header, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testParseNegativePort() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Port=\"80,-800,8000\";Version=1"); try { cookiespec.parse(header, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } /** * test parsing cookie name/value. */ @Test public void testParseNameValue() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Version=1;"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertEquals("name", cookie.getName()); Assert.assertEquals("value", cookie.getValue()); } /** * test parsing cookie "Version" attribute. */ @Test public void testParseVersion() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Version=1;"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertEquals(1, cookie.getVersion()); Assert.assertTrue(cookie.containsAttribute(ClientCookie.VERSION_ATTR)); } @Test public void testParseNullVersion() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); // version cannot be null final Header header = new BasicHeader("Set-Cookie2", "name=value;Version=;"); try { cookiespec.parse(header, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testParseNegativeVersion() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Version=-1;"); try { cookiespec.parse(header, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } /** * test parsing cookie "Max-age" attribute. */ @Test public void testParseMaxage() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Max-age=3600;Version=1;Max-age=nonsense"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); // only the first occurence of max-age attribute is considered, others ignored final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertFalse(cookie.isExpired(new Date())); } @Test public void testParseMaxageDefault() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); // Max-age is OPTIONAL, defaults to session cookie final Header header = new BasicHeader("Set-Cookie2", "name=value;Version=1"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertFalse(cookie.isPersistent()); } @Test public void testParseNullMaxage() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Max-age=;Version=1"); try { cookiespec.parse(header, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testParseNegativeMaxage() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Max-age=-3600;Version=1;"); try { cookiespec.parse(header, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } /** * test parsing "Secure" attribute. */ @Test public void testParseSecure() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Secure;Version=1"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertTrue(cookie.isSecure()); } /** * test parsing "Discard" attribute. */ @Test public void testParseDiscard() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); Header header = new BasicHeader("Set-Cookie2", "name=value;Discard;Max-age=36000;Version=1"); List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); ClientCookie cookie = (ClientCookie) cookies.get(0); // discard overrides max-age Assert.assertFalse(cookie.isPersistent()); // Discard is OPTIONAL, default behavior is dictated by max-age header = new BasicHeader("Set-Cookie2", "name=value;Max-age=36000;Version=1"); cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); cookie = (ClientCookie) cookies.get(0); Assert.assertTrue(cookie.isPersistent()); } /** * test parsing "Comment", "CommentURL" and * "Secure" attributes. */ @Test public void testParseOtherAttributes() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); Header header = new BasicHeader("Set-Cookie2", "name=value;Comment=\"good cookie\";" + "CommentURL=\"www.domain.com/goodcookie/\";Secure;Version=1"); List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertEquals("good cookie", cookie.getComment()); Assert.assertEquals("www.domain.com/goodcookie/", cookie.getCommentURL()); Assert.assertTrue(cookie.isSecure()); // Comment, CommentURL, Secure are OPTIONAL header = new BasicHeader("Set-Cookie2", "name=value;Version=1"); cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); cookie = (ClientCookie) cookies.get(0); Assert.assertFalse(cookie.isSecure()); } /** * Test parsing header with 2 cookies (separated by comma) */ @Test public void testCookiesWithComma() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "a=b,c"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(2, cookies.size()); Assert.assertEquals("a", cookies.get(0).getName()); Assert.assertEquals("b", cookies.get(0).getValue()); Assert.assertEquals("c", cookies.get(1).getName()); Assert.assertEquals(null, cookies.get(1).getValue()); } // ------------------------------------------------------- Test Cookie Validation /** * Test Domain validation when domain is not specified * in Set-Cookie2 header. */ @Test public void testValidateNoDomain() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Version=1"); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); // cookie domain must string match request host Assert.assertEquals("www.domain.com", cookie.getDomain()); } /** * Test Domain validation. Cookie domain attribute must have a * leading dot. */ @Test public void testValidateDomainLeadingDot() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value;Domain=domain.com;Version=1"); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertEquals(".domain.com", cookie.getDomain()); } /** * Test Domain validation. Domain must have at least one embedded dot. */ @Test public void testValidateDomainEmbeddedDot() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); CookieOrigin origin = new CookieOrigin("b.com", 80, "/", false); Header header = new BasicHeader("Set-Cookie2", "name=value; domain=.com; version=1"); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException expected) {} origin = new CookieOrigin("www.domain.com", 80, "/", false); header = new BasicHeader("Set-Cookie2", "name=value;Domain=domain.com;Version=1"); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); } /** * Test local Domain validation. Simple host names * (without any dots) are valid only when cookie domain is specified * as ".local". */ @Test public void testValidateDomainLocal() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("simplehost", 80, "/", false); // when domain is specified as .local, simple host names are valid Header header = new BasicHeader("Set-Cookie2", "name=value; domain=.local; version=1"); List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertEquals(".local", cookie.getDomain()); // when domain is NOT specified as .local, simple host names are invalid header = new BasicHeader("Set-Cookie2", "name=value; domain=domain.com; version=1"); try { // since domain is not .local, this must Assert.fail cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException expected) {} } @Test public void testValidateDomainLocalhost() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("localhost", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value; version=1"); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertEquals("localhost.local", cookie.getDomain()); } /** * Test Domain validation. Effective host name * must domain-match domain attribute. */ @Test public void testValidateDomainEffectiveHost() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); // cookie domain does not domain-match request host Header header = new BasicHeader("Set-Cookie2", "name=value; domain=.domain.com; version=1"); try { final CookieOrigin origin = new CookieOrigin("www.domain.org", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException expected) {} final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); // cookie domain domain-matches request host header = new BasicHeader("Set-Cookie2", "name=value; domain=.domain.com; version=1"); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); } /** * Test local Domain validation. * Effective host name minus domain must not contain any dots. */ @Test public void testValidateDomainIllegal() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("a.b.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie2", "name=value; domain=.domain.com; version=1"); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException expected) {} } /** * Test cookie Path validation. Cookie path attribute must path-match * request path. */ @Test public void testValidatePath() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); Header header = new BasicHeader("Set-Cookie2", "name=value;path=/path;version=1"); try { final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException exception should have been thrown"); } catch (final MalformedCookieException expected) {} // path-matching is case-sensitive header = new BasicHeader("Set-Cookie2", "name=value;path=/Path;version=1"); try { final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/path", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException exception should have been thrown"); } catch (final MalformedCookieException expected) {} final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/path/path1", false); header = new BasicHeader("Set-Cookie2", "name=value;path=/path;version=1"); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); Assert.assertEquals("/path", cookies.get(0).getPath()); } /** * Test cookie name validation. */ @Test public void testValidateCookieName() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("127.0.0.1", 80, "/", false); // cookie name must not contain blanks Header header = new BasicHeader("Set-Cookie2", "invalid name=value; version=1"); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException exception should have been thrown"); } catch (final MalformedCookieException expected) {} // cookie name must not start with '$'. header = new BasicHeader("Set-Cookie2", "$invalid_name=value; version=1"); try { final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException exception should have been thrown"); } catch (final MalformedCookieException expected) {} // valid name header = new BasicHeader("Set-Cookie2", "name=value; version=1"); final List cookies = cookiespec.parse(header, origin); Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); Assert.assertEquals("name", cookie.getName()); Assert.assertEquals("value", cookie.getValue()); } /** * Test cookie Port validation. Request port must be in the * port attribute list. */ @Test public void testValidatePort() throws Exception { final Header header = new BasicHeader("Set-Cookie2", "name=value; Port=\"80,800\"; version=1"); final CookieSpec cookiespec = new RFC2965Spec(); try { final CookieOrigin origin = new CookieOrigin("www.domain.com", 8000, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException e) {} // valid port list final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.assertNotNull(cookies); Assert.assertEquals(1, cookies.size()); final ClientCookie cookie = (ClientCookie) cookies.get(0); final int[] ports = cookie.getPorts(); Assert.assertNotNull(ports); Assert.assertEquals(2, ports.length); Assert.assertEquals(80, ports[0]); Assert.assertEquals(800, ports[1]); } /** * Test cookie Version validation. */ @Test public void testValidateVersion() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); // version attribute is REQUIRED final Header header = new BasicHeader("Set-Cookie2", "name=value"); try { final CookieOrigin origin = new CookieOrigin("www.domain.com", 8000, "/", false); final List cookies = cookiespec.parse(header, origin); for (int i = 0; i < cookies.size(); i++) { cookiespec.validate(cookies.get(i), origin); } Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException e) {} } // ------------------------------------------------------- Test Cookie Matching /** * test cookie Path matching. Cookie path attribute must path-match * path of the request URI. */ @Test public void testMatchPath() throws Exception { final BasicClientCookie2 cookie = new BasicClientCookie2("name", "value"); cookie.setDomain(".domain.com"); cookie.setPath("/path"); cookie.setPorts(new int[] {80}); final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin1 = new CookieOrigin("www.domain.com", 80, "/", false); Assert.assertFalse(cookiespec.match(cookie, origin1)); final CookieOrigin origin2 = new CookieOrigin("www.domain.com", 80, "/path/path1", false); Assert.assertTrue(cookiespec.match(cookie, origin2)); } /** * test cookie Domain matching. */ @Test public void testMatchDomain() throws Exception { final BasicClientCookie2 cookie = new BasicClientCookie2("name", "value"); cookie.setDomain(".domain.com"); cookie.setPath("/"); cookie.setPorts(new int[] {80}); final CookieSpec cookiespec = new RFC2965Spec(); // effective host name minus domain must not contain any dots final CookieOrigin origin1 = new CookieOrigin("a.b.domain.com" /* request host */, 80, "/", false); Assert.assertFalse(cookiespec.match(cookie, origin1)); // The effective host name MUST domain-match the Domain // attribute of the cookie. final CookieOrigin origin2 = new CookieOrigin("www.domain.org" /* request host */, 80, "/", false); Assert.assertFalse(cookiespec.match(cookie, origin2)); final CookieOrigin origin3 = new CookieOrigin("www.domain.com" /* request host */, 80, "/", false); Assert.assertTrue(cookiespec.match(cookie, origin3)); } /** * test cookie local Domain matching. */ @Test public void testMatchDomainLocal() throws Exception { final BasicClientCookie2 cookie = new BasicClientCookie2("name", "value"); cookie.setDomain(".local"); cookie.setPath("/"); cookie.setPorts(new int[] {80}); final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin1 = new CookieOrigin("host" /* request host */, 80, "/", false); Assert.assertTrue(cookiespec.match(cookie, origin1)); final CookieOrigin origin2 = new CookieOrigin("host.com" /* request host */, 80, "/", false); Assert.assertFalse(cookiespec.match(cookie, origin2)); } /** * test cookie Port matching. */ @Test public void testMatchPort() throws Exception { // cookie can be sent to any port if port attribute not specified BasicClientCookie2 cookie = new BasicClientCookie2("name", "value"); cookie.setDomain(".domain.com"); cookie.setPath("/"); cookie.setPorts(null); final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin1 = new CookieOrigin("www.domain.com", 8080 /* request port */, "/", false); Assert.assertTrue(cookiespec.match(cookie, origin1)); final CookieOrigin origin2 = new CookieOrigin("www.domain.com", 323 /* request port */, "/", false); Assert.assertTrue(cookiespec.match(cookie, origin2)); // otherwise, request port must be in cookie's port list cookie = new BasicClientCookie2("name", "value"); cookie.setDomain(".domain.com"); cookie.setPath("/"); cookie.setPorts(new int[] {80, 8080}); cookie.setAttribute(ClientCookie.PORT_ATTR, "80, 8080"); final CookieOrigin origin3 = new CookieOrigin("www.domain.com", 434 /* request port */, "/", false); Assert.assertFalse(cookiespec.match(cookie, origin3)); final CookieOrigin origin4 = new CookieOrigin("www.domain.com", 8080 /* request port */, "/", false); Assert.assertTrue(cookiespec.match(cookie, origin4)); } /** * test cookie expiration. */ @Test public void testCookieExpiration() throws Exception { final Date now = new Date(); final Date beforeOneHour = new Date(now.getTime() - 3600 * 1000L); BasicClientCookie2 cookie = new BasicClientCookie2("name", "value"); cookie.setDomain(".domain.com"); cookie.setPath("/"); cookie.setPorts(null); cookie.setExpiryDate(beforeOneHour); Assert.assertTrue(cookie.isExpired(now)); final Date afterOneHour = new Date(now.getTime() + 3600 * 1000L); cookie = new BasicClientCookie2("name", "value"); cookie.setDomain(".domain.com"); cookie.setPath("/"); cookie.setPorts(null); cookie.setExpiryDate(afterOneHour); Assert.assertFalse(cookie.isExpired(now)); // discard attributes overrides cookie age, makes it a session cookie. cookie.setDiscard(true); Assert.assertFalse(cookie.isPersistent()); Assert.assertTrue(cookie.isExpired(now)); } /** * test cookie Secure attribute. */ @Test public void testCookieSecure() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); // secure cookie can only be sent over a secure connection final BasicClientCookie2 cookie = new BasicClientCookie2("name", "value"); cookie.setDomain(".domain.com"); cookie.setPath("/"); cookie.setSecure(true); final CookieOrigin origin1 = new CookieOrigin("www.domain.com", 80, "/", false); Assert.assertFalse(cookiespec.match(cookie, origin1)); final CookieOrigin origin2 = new CookieOrigin("www.domain.com", 80, "/", true); Assert.assertTrue(cookiespec.match(cookie, origin2)); } // ------------------------------------------------------- Test Cookie Formatting /** * Tests RFC 2965 compliant cookie formatting. */ @Test public void testRFC2965CookieFormatting() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(null, true); final BasicClientCookie2 cookie1 = new BasicClientCookie2("name1", "value"); cookie1.setDomain(".domain.com"); cookie1.setPath("/"); cookie1.setPorts(new int[] {80,8080}); cookie1.setVersion(1); // domain, path, port specified cookie1.setAttribute(ClientCookie.DOMAIN_ATTR, ".domain.com"); cookie1.setAttribute(ClientCookie.PATH_ATTR, "/"); cookie1.setAttribute(ClientCookie.PORT_ATTR, "80,8080"); List cookies = new ArrayList(); cookies.add(cookie1); List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("$Version=1; name1=\"value\"; $Path=\"/\"; $Domain=\".domain.com\"; $Port=\"80,8080\"", headers.get(0).getValue()); final BasicClientCookie2 cookie2 = new BasicClientCookie2("name2", "value"); cookie2.setDomain(".domain.com"); cookie2.setPath("/a/"); cookie2.setPorts(new int[] {80,8080}); cookie2.setVersion(2); // domain, path specified but port unspecified cookie2.setAttribute(ClientCookie.DOMAIN_ATTR, ".domain.com"); cookie2.setAttribute(ClientCookie.PATH_ATTR, "/a/"); cookies = new ArrayList(); cookies.add(cookie2); headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("$Version=2; name2=\"value\"; $Path=\"/a/\"; $Domain=\".domain.com\"", headers.get(0).getValue()); final BasicClientCookie2 cookie3 = new BasicClientCookie2("name3", "value"); cookie3.setDomain(".domain.com"); cookie3.setPath("/a/b/"); cookie3.setPorts(new int[] {80,8080}); cookie3.setVersion(1); // path specified, port specified but blank, domain unspecified cookie3.setAttribute(ClientCookie.PATH_ATTR, "/a/b/"); cookie3.setAttribute(ClientCookie.PORT_ATTR, " "); cookies = new ArrayList(); cookies.add(cookie3); headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("$Version=1; name3=\"value\"; $Path=\"/a/b/\"; $Port=\"\"", headers.get(0).getValue()); cookies = new ArrayList(); cookies.add(cookie3); cookies.add(cookie2); cookies.add(cookie1); headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("$Version=1; " + "name3=\"value\"; $Path=\"/a/b/\"; $Port=\"\"; " + "name2=\"value\"; $Path=\"/a/\"; $Domain=\".domain.com\"; " + "name1=\"value\"; $Path=\"/\"; $Domain=\".domain.com\"; $Port=\"80,8080\"", headers.get(0).getValue()); } /** * Tests RFC 2965 compliant cookies formatting. */ @Test public void testRFC2965CookiesFormatting() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(null, true); final BasicClientCookie2 cookie1 = new BasicClientCookie2("name1", "value1"); cookie1.setDomain(".domain.com"); cookie1.setPath("/"); cookie1.setPorts(new int[] {80,8080}); cookie1.setVersion(1); // domain, path, port specified cookie1.setAttribute(ClientCookie.DOMAIN_ATTR, ".domain.com"); cookie1.setAttribute(ClientCookie.PATH_ATTR, "/"); cookie1.setAttribute(ClientCookie.PORT_ATTR, "80,8080"); final BasicClientCookie2 cookie2 = new BasicClientCookie2("name2", ""); cookie2.setDomain(".domain.com"); cookie2.setPath("/"); cookie2.setPorts(new int[] {80,8080}); cookie2.setVersion(1); // value null, domain, path specified cookie2.setAttribute(ClientCookie.DOMAIN_ATTR, ".domain.com"); cookie2.setAttribute(ClientCookie.PATH_ATTR, "/"); final List cookies = new ArrayList(); cookies.add(cookie1); cookies.add(cookie2); final List
headers = cookiespec.formatCookies(cookies); Assert.assertNotNull(headers); Assert.assertEquals(1, headers.size()); Assert.assertEquals("$Version=1; name1=\"value1\"; $Path=\"/\"; $Domain=\".domain.com\"; $Port=\"80,8080\"; " + "name2=\"\"; $Path=\"/\"; $Domain=\".domain.com\"", headers.get(0).getValue()); } // ------------------------------------------------------- Backward compatibility tests /** * Test rejection of Set-Cookie header. */ @Test public void testRejectSetCookie() throws Exception { final CookieSpec cookiespec = new RFC2965Spec(); final CookieOrigin origin = new CookieOrigin("www.domain.com", 80, "/", false); final Header header = new BasicHeader("Set-Cookie", "name=value; domain=.domain.com; version=1"); try { cookiespec.parse(header, origin); } catch (final MalformedCookieException ex) { // expected } } } ././@LongLink0100644 0000000 0000000 00000000167 12302131605 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestNetscapeCookieAttribHandlers.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestNetscapeCookieA0100644 0000000 0000000 00000013411 12301751655 032444 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; import org.junit.Assert; import org.junit.Test; public class TestNetscapeCookieAttribHandlers { @Test public void testNetscapeDomainValidate1() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somehost", 80, "/", false); final CookieAttributeHandler h = new NetscapeDomainHandler(); cookie.setDomain("somehost"); h.validate(cookie, origin); cookie.setDomain("otherhost"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testNetscapeDomainValidate2() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("www.somedomain.com", 80, "/", false); final CookieAttributeHandler h = new NetscapeDomainHandler(); cookie.setDomain(".somedomain.com"); h.validate(cookie, origin); cookie.setDomain(".otherdomain.com"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } cookie.setDomain("www.otherdomain.com"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testNetscapeDomainValidate3() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("www.a.com", 80, "/", false); final CookieAttributeHandler h = new NetscapeDomainHandler(); cookie.setDomain(".a.com"); h.validate(cookie, origin); cookie.setDomain(".com"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testNetscapeDomainValidate4() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("www.a.b.c", 80, "/", false); final CookieAttributeHandler h = new NetscapeDomainHandler(); cookie.setDomain(".a.b.c"); h.validate(cookie, origin); cookie.setDomain(".b.c"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testNetscapeDomainMatch1() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("www.somedomain.com", 80, "/", false); final CookieAttributeHandler h = new NetscapeDomainHandler(); cookie.setDomain(null); Assert.assertFalse(h.match(cookie, origin)); cookie.setDomain(".somedomain.com"); Assert.assertTrue(h.match(cookie, origin)); } @Test public void testNetscapeDomainMatch2() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("www.whatever.somedomain.com", 80, "/", false); final CookieAttributeHandler h = new NetscapeDomainHandler(); cookie.setDomain(".somedomain.com"); Assert.assertTrue(h.match(cookie, origin)); } @Test public void testNetscapeDomainInvalidInput() throws Exception { final CookieAttributeHandler h = new NetscapeDomainHandler(); try { h.match(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { h.match(new BasicClientCookie("name", "value"), null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } } } ././@LongLink0100644 0000000 0000000 00000000164 12302131605 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestNetscapeDraftHeaderParser.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestNetscapeDraftHe0100644 0000000 0000000 00000006037 12301751655 032455 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.HeaderElement; import org.apache.http.NameValuePair; import org.apache.http.message.ParserCursor; import org.apache.http.util.CharArrayBuffer; import org.junit.Assert; import org.junit.Test; /** * Unit tests for {@link NetscapeDraftHeaderParser}. */ public class TestNetscapeDraftHeaderParser { @Test public void testNetscapeCookieParsing() throws Exception { final NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT; String s = "name = value; test; test1 = stuff,with,commas ;" + " test2 = \"stuff, stuff\"; test3=\"stuff"; CharArrayBuffer buffer = new CharArrayBuffer(16); buffer.append(s); ParserCursor cursor = new ParserCursor(0, s.length()); HeaderElement he = parser.parseHeader(buffer, cursor); Assert.assertEquals("name", he.getName()); Assert.assertEquals("value", he.getValue()); final NameValuePair[] params = he.getParameters(); Assert.assertEquals("test", params[0].getName()); Assert.assertEquals(null, params[0].getValue()); Assert.assertEquals("test1", params[1].getName()); Assert.assertEquals("stuff,with,commas", params[1].getValue()); Assert.assertEquals("test2", params[2].getName()); Assert.assertEquals("\"stuff, stuff\"", params[2].getValue()); Assert.assertEquals("test3", params[3].getName()); Assert.assertEquals("\"stuff", params[3].getValue()); Assert.assertEquals(s.length(), cursor.getPos()); Assert.assertTrue(cursor.atEnd()); s = " "; buffer = new CharArrayBuffer(16); buffer.append(s); cursor = new ParserCursor(0, s.length()); he = parser.parseHeader(buffer, cursor); Assert.assertEquals("", he.getName()); Assert.assertEquals(null, he.getValue()); } } ././@LongLink0100644 0000000 0000000 00000000161 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestPublicSuffixListParser.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestPublicSuffixLis0100644 0000000 0000000 00000007720 12301751655 032530 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import java.io.InputStreamReader; import java.io.Reader; import org.apache.http.cookie.CookieOrigin; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestPublicSuffixListParser { private static final String LIST_FILE = "/suffixlist.txt"; private PublicSuffixFilter filter; @Before public void setUp() throws Exception { final Reader r = new InputStreamReader(getClass().getResourceAsStream(LIST_FILE), "UTF-8"); filter = new PublicSuffixFilter(new RFC2109DomainHandler()); final PublicSuffixListParser parser = new PublicSuffixListParser(filter); parser.parse(r); } @Test public void testParse() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain(".jp"); Assert.assertFalse(filter.match(cookie, new CookieOrigin("apache.jp", 80, "/stuff", false))); cookie.setDomain(".ac.jp"); Assert.assertFalse(filter.match(cookie, new CookieOrigin("apache.ac.jp", 80, "/stuff", false))); cookie.setDomain(".any.tokyo.jp"); Assert.assertFalse(filter.match(cookie, new CookieOrigin("apache.any.tokyo.jp", 80, "/stuff", false))); // exception cookie.setDomain(".metro.tokyo.jp"); Assert.assertTrue(filter.match(cookie, new CookieOrigin("apache.metro.tokyo.jp", 80, "/stuff", false))); } @Test public void testUnicode() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain(".h\u00E5.no"); // \u00E5 is Assert.assertFalse(filter.match(cookie, new CookieOrigin("apache.h\u00E5.no", 80, "/stuff", false))); cookie.setDomain(".xn--h-2fa.no"); Assert.assertFalse(filter.match(cookie, new CookieOrigin("apache.xn--h-2fa.no", 80, "/stuff", false))); cookie.setDomain(".h\u00E5.no"); Assert.assertFalse(filter.match(cookie, new CookieOrigin("apache.xn--h-2fa.no", 80, "/stuff", false))); cookie.setDomain(".xn--h-2fa.no"); Assert.assertFalse(filter.match(cookie, new CookieOrigin("apache.h\u00E5.no", 80, "/stuff", false))); } @Test public void testWhitespace() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); cookie.setDomain(".xx"); Assert.assertFalse(filter.match(cookie, new CookieOrigin("apache.xx", 80, "/stuff", false))); // yy appears after whitespace cookie.setDomain(".yy"); Assert.assertTrue(filter.match(cookie, new CookieOrigin("apache.yy", 80, "/stuff", false))); // zz is commented cookie.setDomain(".zz"); Assert.assertTrue(filter.match(cookie, new CookieOrigin("apache.zz", 80, "/stuff", false))); } } ././@LongLink0100644 0000000 0000000 00000000166 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestRFC2109CookieAttribHandlers.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/cookie/TestRFC2109CookieAt0100644 0000000 0000000 00000025455 12301751655 032027 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.cookie; import org.apache.http.cookie.CookieAttributeHandler; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.MalformedCookieException; import org.junit.Assert; import org.junit.Test; public class TestRFC2109CookieAttribHandlers { @Test public void testRFC2109DomainParse() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new RFC2109DomainHandler(); h.parse(cookie, "somehost"); Assert.assertEquals("somehost", cookie.getDomain()); try { h.parse(cookie, null); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } try { h.parse(cookie, " "); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testRFC2109DomainValidate1() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somehost", 80, "/", false); final CookieAttributeHandler h = new RFC2109DomainHandler(); cookie.setDomain("somehost"); h.validate(cookie, origin); cookie.setDomain("otherhost"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } cookie.setDomain(null); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testRFC2109DomainValidate2() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("www.somedomain.com", 80, "/", false); final CookieAttributeHandler h = new RFC2109DomainHandler(); cookie.setDomain(".somedomain.com"); h.validate(cookie, origin); cookie.setDomain(".otherdomain.com"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } cookie.setDomain("www.otherdomain.com"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testRFC2109DomainValidate3() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("www.a.com", 80, "/", false); final CookieAttributeHandler h = new RFC2109DomainHandler(); cookie.setDomain(".a.com"); h.validate(cookie, origin); cookie.setDomain(".com"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testRFC2109DomainValidate4() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("www.a.b.c", 80, "/", false); final CookieAttributeHandler h = new RFC2109DomainHandler(); cookie.setDomain(".a.b.c"); h.validate(cookie, origin); cookie.setDomain(".b.c"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } cookie.setDomain(".a.a.b.c"); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException should have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testRFC2109DomainMatch1() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("www.somedomain.com", 80, "/", false); final CookieAttributeHandler h = new RFC2109DomainHandler(); cookie.setDomain(null); Assert.assertFalse(h.match(cookie, origin)); cookie.setDomain(".somedomain.com"); Assert.assertTrue(h.match(cookie, origin)); } @Test public void testRFC2109DomainMatch2() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("www.whatever.somedomain.com", 80, "/", false); final CookieAttributeHandler h = new RFC2109DomainHandler(); cookie.setDomain(".somedomain.com"); Assert.assertTrue(h.match(cookie, origin)); } @Test public void testRFC2109DomainMatch3() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somedomain.com", 80, "/", false); final CookieAttributeHandler h = new RFC2109DomainHandler(); cookie.setDomain("somedomain.com"); Assert.assertTrue(h.match(cookie, origin)); } @Test public void testRFC2109DomainMatch4() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("www.somedomain.com", 80, "/", false); final CookieAttributeHandler h = new RFC2109DomainHandler(); cookie.setDomain("somedomain.com"); Assert.assertFalse(h.match(cookie, origin)); } @Test public void testRFC2109DomainInvalidInput() throws Exception { final CookieAttributeHandler h = new RFC2109DomainHandler(); try { h.parse(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { h.validate(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { h.validate(new BasicClientCookie("name", "value"), null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { h.match(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { h.match(new BasicClientCookie("name", "value"), null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } } @Test public void testRFC2109VersionParse() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new RFC2109VersionHandler(); h.parse(cookie, "12"); Assert.assertEquals(12, cookie.getVersion()); } @Test public void testRFC2109VersionParseInvalid() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new RFC2109VersionHandler(); try { h.parse(cookie, "garbage"); Assert.fail("MalformedCookieException must have been thrown"); } catch (final MalformedCookieException ex) { // expected } try { h.parse(cookie, null); Assert.fail("MalformedCookieException must have been thrown"); } catch (final MalformedCookieException ex) { // expected } try { h.parse(cookie, " "); Assert.fail("MalformedCookieException must have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testRFC2109VersionValidate() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieOrigin origin = new CookieOrigin("somedomain.com", 80, "/", false); final CookieAttributeHandler h = new RFC2109VersionHandler(); cookie.setVersion(12); h.validate(cookie, origin); cookie.setVersion(-12); try { h.validate(cookie, origin); Assert.fail("MalformedCookieException must have been thrown"); } catch (final MalformedCookieException ex) { // expected } } @Test public void testRFC2109VersionInvalidInput() throws Exception { final CookieAttributeHandler h = new RFC2109VersionHandler(); try { h.parse(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } try { h.validate(null, null); Assert.fail("IllegalArgumentException must have been thrown"); } catch (final IllegalArgumentException ex) { // expected } } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/0040755 0000000 0000000 00000000000 12301751660 027341 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000156 12302131605 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestConnectionHolder.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestConnectionHo0100644 0000000 0000000 00000011721 12301751660 032511 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.IOException; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.http.HttpClientConnection; import org.apache.http.conn.HttpClientConnectionManager; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; public class TestConnectionHolder { private Log log; private HttpClientConnectionManager mgr; private HttpClientConnection conn; private ConnectionHolder connHolder; @Before public void setup() { log = Mockito.mock(Log.class); mgr = Mockito.mock(HttpClientConnectionManager.class); conn = Mockito.mock(HttpClientConnection.class); connHolder = new ConnectionHolder(log, mgr, conn); } @Test public void testAbortConnection() throws Exception { connHolder.abortConnection(); Assert.assertTrue(connHolder.isReleased()); Mockito.verify(conn).shutdown(); Mockito.verify(mgr).releaseConnection(conn, null, 0, TimeUnit.MILLISECONDS); connHolder.abortConnection(); Mockito.verify(conn, Mockito.times(1)).shutdown(); Mockito.verify(mgr, Mockito.times(1)).releaseConnection( Mockito.any(), Mockito.anyObject(), Mockito.anyLong(), Mockito.any()); } @Test public void testAbortConnectionIOError() throws Exception { Mockito.doThrow(new IOException()).when(conn).shutdown(); connHolder.abortConnection(); Assert.assertTrue(connHolder.isReleased()); Mockito.verify(conn).shutdown(); Mockito.verify(mgr).releaseConnection(conn, null, 0, TimeUnit.MILLISECONDS); } @Test public void testCancell() throws Exception { Assert.assertTrue(connHolder.cancel()); Assert.assertTrue(connHolder.isReleased()); Mockito.verify(conn).shutdown(); Mockito.verify(mgr).releaseConnection(conn, null, 0, TimeUnit.MILLISECONDS); Assert.assertFalse(connHolder.cancel()); Mockito.verify(conn, Mockito.times(1)).shutdown(); Mockito.verify(mgr, Mockito.times(1)).releaseConnection( Mockito.any(), Mockito.anyObject(), Mockito.anyLong(), Mockito.any()); } @Test public void testReleaseConnectionReusable() throws Exception { connHolder.setState("some state"); connHolder.setValidFor(100, TimeUnit.SECONDS); connHolder.markReusable(); connHolder.releaseConnection(); Assert.assertTrue(connHolder.isReleased()); Mockito.verify(conn, Mockito.never()).close(); Mockito.verify(mgr).releaseConnection(conn, "some state", 100, TimeUnit.SECONDS); connHolder.releaseConnection(); Mockito.verify(mgr, Mockito.times(1)).releaseConnection( Mockito.any(), Mockito.anyObject(), Mockito.anyLong(), Mockito.any()); } @Test public void testReleaseConnectionNonReusable() throws Exception { connHolder.setState("some state"); connHolder.setValidFor(100, TimeUnit.SECONDS); connHolder.markNonReusable(); connHolder.releaseConnection(); Assert.assertTrue(connHolder.isReleased()); Mockito.verify(conn, Mockito.times(1)).close(); Mockito.verify(mgr).releaseConnection(conn, null, 0, TimeUnit.MILLISECONDS); connHolder.releaseConnection(); Mockito.verify(mgr, Mockito.times(1)).releaseConnection( Mockito.any(), Mockito.anyObject(), Mockito.anyLong(), Mockito.any()); } } ././@LongLink0100644 0000000 0000000 00000000154 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestMainClientExec.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestMainClientEx0100644 0000000 0000000 00000120025 12301751660 032441 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; import java.lang.reflect.Proxy; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import junit.framework.Assert; import org.apache.http.ConnectionReuseStrategy; import org.apache.http.Header; import org.apache.http.HttpClientConnection; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthOption; import org.apache.http.auth.AuthProtocolState; import org.apache.http.auth.AuthState; import org.apache.http.auth.NTCredentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthenticationStrategy; import org.apache.http.client.NonRepeatableRequestException; import org.apache.http.client.UserTokenHandler; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.EntityBuilder; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.concurrent.Cancellable; import org.apache.http.conn.ConnectionKeepAliveStrategy; import org.apache.http.conn.ConnectionRequest; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.RouteInfo; import org.apache.http.entity.StringEntity; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.auth.NTLMScheme; import org.apache.http.impl.conn.ConnectionShutdownException; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpResponse; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestExecutor; import org.apache.http.util.EntityUtils; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; public class TestMainClientExec { @Mock private HttpRequestExecutor requestExecutor; @Mock private HttpClientConnectionManager connManager; @Mock private ConnectionReuseStrategy reuseStrategy; @Mock private ConnectionKeepAliveStrategy keepAliveStrategy; @Mock private AuthenticationStrategy targetAuthStrategy; @Mock private AuthenticationStrategy proxyAuthStrategy; @Mock private UserTokenHandler userTokenHandler; @Mock private HttpExecutionAware execAware; @Mock private ConnectionRequest connRequest; @Mock private HttpClientConnection managedConn; private MainClientExec mainClientExec; private HttpHost target; private HttpHost proxy; @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); mainClientExec = new MainClientExec(requestExecutor, connManager, reuseStrategy, keepAliveStrategy, targetAuthStrategy, proxyAuthStrategy, userTokenHandler); target = new HttpHost("foo", 80); proxy = new HttpHost("bar", 8888); Mockito.when(connManager.requestConnection( Mockito.any(), Mockito.any())).thenReturn(connRequest); Mockito.when(connRequest.get( Mockito.anyLong(), Mockito.any())).thenReturn(managedConn); final Map challenges = new HashMap(); challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test")); final AuthOption authOption = new AuthOption( new BasicScheme(), new UsernamePasswordCredentials("user:pass")); Mockito.when(targetAuthStrategy.getChallenges( Mockito.eq(target), Mockito.any(), Mockito.any())).thenReturn(challenges); Mockito.when(targetAuthStrategy.getChallenges( Mockito.eq(target), Mockito.any(), Mockito.any())).thenReturn(challenges); Mockito.when(targetAuthStrategy.select( Mockito.same(challenges), Mockito.eq(target), Mockito.any(), Mockito.any())).thenReturn( new LinkedList(Arrays.asList(authOption))); Mockito.when(proxyAuthStrategy.getChallenges( Mockito.eq(proxy), Mockito.any(), Mockito.any())).thenReturn(challenges); Mockito.when(proxyAuthStrategy.getChallenges( Mockito.eq(proxy), Mockito.any(), Mockito.any())).thenReturn(challenges); Mockito.when(proxyAuthStrategy.select( Mockito.same(challenges), Mockito.eq(proxy), Mockito.any(), Mockito.any())).thenReturn( new LinkedList(Arrays.asList(authOption))); } @Test public void testExecRequestNonPersistentConnection() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final RequestConfig config = RequestConfig.custom() .setConnectTimeout(123) .setSocketTimeout(234) .setConnectionRequestTimeout(345) .build(); context.setRequestConfig(config); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response); final CloseableHttpResponse finalResponse = mainClientExec.execute( route, request, context, execAware); Mockito.verify(connManager).requestConnection(route, null); Mockito.verify(connRequest).get(345, TimeUnit.MILLISECONDS); Mockito.verify(execAware, Mockito.times(1)).setCancellable(connRequest); Mockito.verify(execAware, Mockito.times(2)).setCancellable(Mockito.any()); Mockito.verify(connManager).connect(managedConn, route, 123, context); Mockito.verify(connManager).routeComplete(managedConn, route, context); Mockito.verify(managedConn).setSocketTimeout(234); Mockito.verify(requestExecutor, Mockito.times(1)).execute(request, managedConn, context); Mockito.verify(managedConn, Mockito.times(1)).close(); Mockito.verify(connManager).releaseConnection(managedConn, null, 0, TimeUnit.MILLISECONDS); Assert.assertNotNull(context.getTargetAuthState()); Assert.assertNotNull(context.getProxyAuthState()); Assert.assertSame(managedConn, context.getConnection()); Assert.assertNull(context.getUserToken()); Assert.assertNotNull(finalResponse); Assert.assertTrue(Proxy.isProxyClass(finalResponse.getClass())); } @Test public void testExecRequestPersistentConnection() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(managedConn.isStale()).thenReturn(Boolean.FALSE); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response); Mockito.when(reuseStrategy.keepAlive( Mockito.same(response), Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(keepAliveStrategy.getKeepAliveDuration( Mockito.same(response), Mockito.any())).thenReturn(678L); final CloseableHttpResponse finalResponse = mainClientExec.execute( route, request, context, execAware); Mockito.verify(connManager).requestConnection(route, null); Mockito.verify(connRequest).get(0, TimeUnit.MILLISECONDS); Mockito.verify(requestExecutor, Mockito.times(1)).execute(request, managedConn, context); Mockito.verify(connManager).releaseConnection(managedConn, null, 678L, TimeUnit.MILLISECONDS); Mockito.verify(managedConn, Mockito.never()).close(); Assert.assertNotNull(finalResponse); Assert.assertTrue(Proxy.isProxyClass(finalResponse.getClass())); } @Test public void testExecRequestPersistentStatefulConnection() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(managedConn.isStale()).thenReturn(Boolean.FALSE); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response); Mockito.when(reuseStrategy.keepAlive( Mockito.same(response), Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(userTokenHandler.getUserToken( Mockito.any())).thenReturn("this and that"); mainClientExec.execute(route, request, context, execAware); Mockito.verify(connManager).requestConnection(route, null); Mockito.verify(connRequest).get(0, TimeUnit.MILLISECONDS); Mockito.verify(requestExecutor, Mockito.times(1)).execute(request, managedConn, context); Mockito.verify(connManager).releaseConnection(managedConn, "this and that", 0, TimeUnit.MILLISECONDS); Mockito.verify(managedConn, Mockito.never()).close(); Assert.assertEquals("this and that", context.getUserToken()); } @Test public void testExecRequestConnectionRelease() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); // The entity is streaming response.setEntity(EntityBuilder.create() .setStream(new ByteArrayInputStream(new byte[]{})) .build()); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(managedConn.isStale()).thenReturn(Boolean.FALSE); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response); Mockito.when(reuseStrategy.keepAlive( Mockito.same(response), Mockito.any())).thenReturn(Boolean.FALSE); final CloseableHttpResponse finalResponse = mainClientExec.execute( route, request, context, execAware); Mockito.verify(connManager).requestConnection(route, null); Mockito.verify(connRequest).get(0, TimeUnit.MILLISECONDS); Mockito.verify(requestExecutor, Mockito.times(1)).execute(request, managedConn, context); Mockito.verify(connManager, Mockito.never()).releaseConnection( Mockito.same(managedConn), Mockito.any(), Mockito.anyInt(), Mockito.any()); Mockito.verify(managedConn, Mockito.never()).close(); Assert.assertNotNull(finalResponse); Assert.assertTrue(Proxy.isProxyClass(finalResponse.getClass())); finalResponse.close(); Mockito.verify(connManager, Mockito.times(1)).releaseConnection( managedConn, null, 0, TimeUnit.MILLISECONDS); Mockito.verify(managedConn, Mockito.times(1)).shutdown(); } @Test public void testExecRequestStaleConnectionCheck() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final RequestConfig config = RequestConfig.custom() .setStaleConnectionCheckEnabled(true) .build(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); context.setRequestConfig(config); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(managedConn.isStale()).thenReturn(Boolean.TRUE); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response); Mockito.when(reuseStrategy.keepAlive( Mockito.same(response), Mockito.any())).thenReturn(Boolean.TRUE); final CloseableHttpResponse finalResponse = mainClientExec.execute( route, request, context, execAware); Mockito.verify(managedConn, Mockito.times(1)).close(); Assert.assertNotNull(finalResponse); Assert.assertTrue(Proxy.isProxyClass(finalResponse.getClass())); } @Test public void testSocketTimeoutExistingConnection() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final RequestConfig config = RequestConfig.custom().setSocketTimeout(3000).build(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); context.setRequestConfig(config); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); Mockito.when(managedConn.isOpen()).thenReturn(true); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response); mainClientExec.execute(route, request, context, execAware); Mockito.verify(managedConn).setSocketTimeout(3000); } @Test public void testSocketTimeoutReset() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response); mainClientExec.execute(route, request, context, execAware); Mockito.verify(managedConn, Mockito.never()).setSocketTimeout(Mockito.anyInt()); } @Test(expected=RequestAbortedException.class) public void testExecAbortedPriorToConnectionLease() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.FALSE); Mockito.when(execAware.isAborted()).thenReturn(Boolean.TRUE); try { mainClientExec.execute(route, request, context, execAware); } catch (final IOException ex) { Mockito.verify(connRequest, Mockito.times(1)).cancel(); throw ex; } } @Test(expected=RequestAbortedException.class) public void testExecAbortedPriorToConnectionSetup() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.FALSE); Mockito.when(execAware.isAborted()).thenReturn(Boolean.FALSE, Boolean.TRUE); try { mainClientExec.execute(route, request, context, execAware); } catch (final IOException ex) { Mockito.verify(connRequest, Mockito.times(1)).get(0, TimeUnit.MILLISECONDS); Mockito.verify(execAware, Mockito.times(2)).setCancellable(Mockito.any()); Mockito.verify(connManager, Mockito.never()).connect( Mockito.same(managedConn), Mockito.any(), Mockito.anyInt(), Mockito.any()); throw ex; } } @Test(expected=RequestAbortedException.class) public void testExecAbortedPriorToRequestExecution() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.FALSE); Mockito.when(execAware.isAborted()).thenReturn(Boolean.FALSE, Boolean.FALSE, Boolean.TRUE); try { mainClientExec.execute(route, request, context, execAware); } catch (final IOException ex) { Mockito.verify(connRequest, Mockito.times(1)).get(0, TimeUnit.MILLISECONDS); Mockito.verify(connManager, Mockito.times(1)).connect(managedConn, route, 0, context); Mockito.verify(requestExecutor, Mockito.never()).execute( Mockito.same(request), Mockito.any(), Mockito.any()); throw ex; } } @Test(expected=RequestAbortedException.class) public void testExecConnectionRequestFailed() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(connRequest.get(Mockito.anyInt(), Mockito.any())) .thenThrow(new ExecutionException("Opppsie", null)); mainClientExec.execute(route, request, context, execAware); } @Test public void testExecRequestRetryOnAuthChallenge() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 401, "Huh?"); final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3})); response1.setEntity(EntityBuilder.create() .setStream(instream1) .build()); final HttpResponse response2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); final InputStream instream2 = Mockito.spy(new ByteArrayInputStream(new byte[] {2, 3, 4})); response2.setEntity(EntityBuilder.create() .setStream(instream2) .build()); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(managedConn.isStale()).thenReturn(Boolean.FALSE); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response1, response2); Mockito.when(reuseStrategy.keepAlive( Mockito.any(), Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(targetAuthStrategy.isAuthenticationRequested( Mockito.eq(target), Mockito.same(response1), Mockito.any())).thenReturn(Boolean.TRUE); final CloseableHttpResponse finalResponse = mainClientExec.execute( route, request, context, execAware); Mockito.verify(requestExecutor, Mockito.times(2)).execute(request, managedConn, context); Mockito.verify(instream1).close(); Mockito.verify(instream2, Mockito.never()).close(); Assert.assertNotNull(finalResponse); Assert.assertEquals(200, finalResponse.getStatusLine().getStatusCode()); } @Test public void testExecEntityEnclosingRequestRetryOnAuthChallenge() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 401, "Huh?"); final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3})); response1.setEntity(EntityBuilder.create() .setStream(instream1) .build()); final HttpResponse response2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); final InputStream instream2 = Mockito.spy(new ByteArrayInputStream(new byte[] {2, 3, 4})); response2.setEntity(EntityBuilder.create() .setStream(instream2) .build()); final AuthState proxyAuthState = new AuthState(); proxyAuthState.setState(AuthProtocolState.SUCCESS); proxyAuthState.update(new NTLMScheme(), new NTCredentials("user:pass")); final HttpClientContext context = new HttpClientContext(); context.setAttribute(HttpClientContext.PROXY_AUTH_STATE, proxyAuthState); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(managedConn.isStale()).thenReturn(Boolean.FALSE); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response1, response2); Mockito.when(reuseStrategy.keepAlive( Mockito.any(), Mockito.any())).thenReturn(Boolean.FALSE); Mockito.when(targetAuthStrategy.isAuthenticationRequested( Mockito.eq(target), Mockito.same(response1), Mockito.any())).thenReturn(Boolean.TRUE); final CloseableHttpResponse finalResponse = mainClientExec.execute( route, request, context, execAware); Mockito.verify(requestExecutor, Mockito.times(2)).execute(request, managedConn, context); Mockito.verify(managedConn).close(); Mockito.verify(instream2, Mockito.never()).close(); Assert.assertNotNull(finalResponse); Assert.assertEquals(200, finalResponse.getStatusLine().getStatusCode()); Assert.assertNull(proxyAuthState.getAuthScheme()); Assert.assertNull(proxyAuthState.getCredentials()); } @Test(expected = NonRepeatableRequestException.class) public void testExecEntityEnclosingRequest() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpPost post = new HttpPost("http://bar/test"); final InputStream instream0 = new ByteArrayInputStream(new byte[] {1, 2, 3}); post.setEntity(EntityBuilder.create() .setStream(instream0) .build()); final HttpRequestWrapper request = HttpRequestWrapper.wrap(post); final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 401, "Huh?"); final InputStream instream1 = new ByteArrayInputStream(new byte[] {1, 2, 3}); response1.setEntity(EntityBuilder.create() .setStream(instream1) .build()); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(managedConn.isStale()).thenReturn(Boolean.FALSE); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenAnswer(new Answer() { public HttpResponse answer(final InvocationOnMock invocationOnMock) throws Throwable { final Object[] args = invocationOnMock.getArguments(); final HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest) args[0]; request.getEntity().writeTo(new ByteArrayOutputStream()); return response1; } }); Mockito.when(reuseStrategy.keepAlive( Mockito.any(), Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(targetAuthStrategy.isAuthenticationRequested( Mockito.eq(target), Mockito.same(response1), Mockito.any())).thenReturn(Boolean.TRUE); mainClientExec.execute(route, request, context, execAware); } @Test(expected=InterruptedIOException.class) public void testExecConnectionShutDown() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(requestExecutor.execute( Mockito.any(), Mockito.any(), Mockito.any())).thenThrow(new ConnectionShutdownException()); mainClientExec.execute(route, request, context, execAware); } @Test(expected=RuntimeException.class) public void testExecRuntimeException() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(requestExecutor.execute( Mockito.any(), Mockito.any(), Mockito.any())).thenThrow(new RuntimeException("Ka-boom")); try { mainClientExec.execute(route, request, context, execAware); } catch (final Exception ex) { Mockito.verify(connManager).releaseConnection(managedConn, null, 0, TimeUnit.MILLISECONDS); throw ex; } } @Test(expected=HttpException.class) public void testExecHttpException() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(requestExecutor.execute( Mockito.any(), Mockito.any(), Mockito.any())).thenThrow(new HttpException("Ka-boom")); try { mainClientExec.execute(route, request, context, execAware); } catch (final Exception ex) { Mockito.verify(connManager).releaseConnection(managedConn, null, 0, TimeUnit.MILLISECONDS); throw ex; } } @Test(expected=IOException.class) public void testExecIOException() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(requestExecutor.execute( Mockito.any(), Mockito.any(), Mockito.any())).thenThrow(new IOException("Ka-boom")); try { mainClientExec.execute(route, request, context, execAware); } catch (final Exception ex) { Mockito.verify(connManager).releaseConnection(managedConn, null, 0, TimeUnit.MILLISECONDS); throw ex; } } @Test public void testEstablishDirectRoute() throws Exception { final AuthState authState = new AuthState(); final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); mainClientExec.establishRoute(authState, managedConn, route, request, context); Mockito.verify(connManager).connect(managedConn, route, 0, context); Mockito.verify(connManager).routeComplete(managedConn, route, context); } @Test public void testEstablishRouteDirectProxy() throws Exception { final AuthState authState = new AuthState(); final HttpRoute route = new HttpRoute(target, null, proxy, false); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); mainClientExec.establishRoute(authState, managedConn, route, request, context); Mockito.verify(connManager).connect(managedConn, route, 0, context); Mockito.verify(connManager).routeComplete(managedConn, route, context); } @Test public void testEstablishRouteViaProxyTunnel() throws Exception { final AuthState authState = new AuthState(); final HttpRoute route = new HttpRoute(target, null, proxy, true); final HttpClientContext context = new HttpClientContext(); final RequestConfig config = RequestConfig.custom() .setConnectTimeout(321) .build(); context.setRequestConfig(config); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(requestExecutor.execute( Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(response); mainClientExec.establishRoute(authState, managedConn, route, request, context); Mockito.verify(connManager).connect(managedConn, route, 321, context); Mockito.verify(connManager).routeComplete(managedConn, route, context); final ArgumentCaptor reqCaptor = ArgumentCaptor.forClass(HttpRequest.class); Mockito.verify(requestExecutor).execute( reqCaptor.capture(), Mockito.same(managedConn), Mockito.same(context)); final HttpRequest connect = reqCaptor.getValue(); Assert.assertNotNull(connect); Assert.assertEquals("CONNECT", connect.getRequestLine().getMethod()); Assert.assertEquals(HttpVersion.HTTP_1_1, connect.getRequestLine().getProtocolVersion()); Assert.assertEquals("foo:80", connect.getRequestLine().getUri()); } @Test(expected = HttpException.class) public void testEstablishRouteViaProxyTunnelUnexpectedResponse() throws Exception { final AuthState authState = new AuthState(); final HttpRoute route = new HttpRoute(target, null, proxy, true); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 101, "Lost"); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(requestExecutor.execute( Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(response); mainClientExec.establishRoute(authState, managedConn, route, request, context); } @Test(expected = HttpException.class) public void testEstablishRouteViaProxyTunnelFailure() throws Exception { final AuthState authState = new AuthState(); final HttpRoute route = new HttpRoute(target, null, proxy, true); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 500, "Boom"); response.setEntity(new StringEntity("Ka-boom")); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(requestExecutor.execute( Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(response); try { mainClientExec.establishRoute(authState, managedConn, route, request, context); } catch (final TunnelRefusedException ex) { final HttpResponse r = ex.getResponse(); Assert.assertEquals("Ka-boom", EntityUtils.toString(r.getEntity())); Mockito.verify(managedConn).close(); throw ex; } } @Test public void testEstablishRouteViaProxyTunnelRetryOnAuthChallengePersistentConnection() throws Exception { final AuthState authState = new AuthState(); final HttpRoute route = new HttpRoute(target, null, proxy, true); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 401, "Huh?"); final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3})); response1.setEntity(EntityBuilder.create() .setStream(instream1) .build()); final HttpResponse response2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(proxyAuthStrategy.isAuthenticationRequested( Mockito.eq(proxy), Mockito.same(response1), Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(reuseStrategy.keepAlive( Mockito.any(), Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(requestExecutor.execute( Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(response1, response2); mainClientExec.establishRoute(authState, managedConn, route, request, context); Mockito.verify(connManager).connect(managedConn, route, 0, context); Mockito.verify(connManager).routeComplete(managedConn, route, context); Mockito.verify(instream1).close(); } @Test public void testEstablishRouteViaProxyTunnelRetryOnAuthChallengeNonPersistentConnection() throws Exception { final AuthState authState = new AuthState(); final HttpRoute route = new HttpRoute(target, null, proxy, true); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 401, "Huh?"); final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3})); response1.setEntity(EntityBuilder.create() .setStream(instream1) .build()); final HttpResponse response2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(proxyAuthStrategy.isAuthenticationRequested( Mockito.eq(proxy), Mockito.same(response1), Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(reuseStrategy.keepAlive( Mockito.any(), Mockito.any())).thenReturn(Boolean.FALSE); Mockito.when(requestExecutor.execute( Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(response1, response2); mainClientExec.establishRoute(authState, managedConn, route, request, context); Mockito.verify(connManager).connect(managedConn, route, 0, context); Mockito.verify(connManager).routeComplete(managedConn, route, context); Mockito.verify(instream1, Mockito.never()).close(); Mockito.verify(managedConn).close(); } @Test(expected = HttpException.class) public void testEstablishRouteViaProxyTunnelMultipleHops() throws Exception { final AuthState authState = new AuthState(); final HttpHost proxy1 = new HttpHost("this", 8888); final HttpHost proxy2 = new HttpHost("that", 8888); final HttpRoute route = new HttpRoute(target, null, new HttpHost[] {proxy1, proxy2}, true, RouteInfo.TunnelType.TUNNELLED, RouteInfo.LayerType.LAYERED); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); mainClientExec.establishRoute(authState, managedConn, route, request, context); } }././@LongLink0100644 0000000 0000000 00000000157 12302131605 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestMinimalClientExec.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestMinimalClien0100644 0000000 0000000 00000041032 12301751660 032462 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import junit.framework.Assert; import org.apache.http.ConnectionReuseStrategy; import org.apache.http.HttpClientConnection; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.EntityBuilder; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.concurrent.Cancellable; import org.apache.http.conn.ConnectionKeepAliveStrategy; import org.apache.http.conn.ConnectionRequest; import org.apache.http.conn.HttpClientConnectionManager; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.impl.conn.ConnectionShutdownException; import org.apache.http.message.BasicHttpResponse; import org.apache.http.protocol.HttpRequestExecutor; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import static org.junit.Assert.assertEquals; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InterruptedIOException; import java.lang.reflect.Proxy; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; public class TestMinimalClientExec { @Mock private HttpRequestExecutor requestExecutor; @Mock private HttpClientConnectionManager connManager; @Mock private ConnectionReuseStrategy reuseStrategy; @Mock private ConnectionKeepAliveStrategy keepAliveStrategy; @Mock private HttpExecutionAware execAware; @Mock private ConnectionRequest connRequest; @Mock private HttpClientConnection managedConn; private MinimalClientExec minimalClientExec; private HttpHost target; @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); minimalClientExec = new MinimalClientExec( requestExecutor, connManager, reuseStrategy, keepAliveStrategy); target = new HttpHost("foo", 80); Mockito.when(connManager.requestConnection( Mockito.any(), Mockito.any())).thenReturn(connRequest); Mockito.when(connRequest.get( Mockito.anyLong(), Mockito.any())).thenReturn(managedConn); } @Test public void testExecRequestNonPersistentConnection() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final RequestConfig config = RequestConfig.custom() .setConnectTimeout(123) .setSocketTimeout(234) .setConnectionRequestTimeout(345) .build(); context.setRequestConfig(config); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response); final CloseableHttpResponse finalResponse = minimalClientExec.execute( route, request, context, execAware); Mockito.verify(connManager).requestConnection(route, null); Mockito.verify(connRequest).get(345, TimeUnit.MILLISECONDS); Mockito.verify(execAware, Mockito.times(1)).setCancellable(connRequest); Mockito.verify(execAware, Mockito.times(2)).setCancellable(Mockito.any()); Mockito.verify(connManager).connect(managedConn, route, 123, context); Mockito.verify(connManager).routeComplete(managedConn, route, context); Mockito.verify(managedConn).setSocketTimeout(234); Mockito.verify(requestExecutor, Mockito.times(1)).execute(request, managedConn, context); Mockito.verify(managedConn, Mockito.times(1)).close(); Mockito.verify(connManager).releaseConnection(managedConn, null, 0, TimeUnit.MILLISECONDS); Assert.assertSame(managedConn, context.getConnection()); Assert.assertNotNull(finalResponse); Assert.assertTrue(Proxy.isProxyClass(finalResponse.getClass())); } @Test public void testExecRequestPersistentConnection() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(managedConn.isStale()).thenReturn(Boolean.FALSE); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response); Mockito.when(reuseStrategy.keepAlive( Mockito.same(response), Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(keepAliveStrategy.getKeepAliveDuration( Mockito.same(response), Mockito.any())).thenReturn(678L); final CloseableHttpResponse finalResponse = minimalClientExec.execute( route, request, context, execAware); Mockito.verify(connManager).requestConnection(route, null); Mockito.verify(connRequest).get(0, TimeUnit.MILLISECONDS); Mockito.verify(requestExecutor, Mockito.times(1)).execute(request, managedConn, context); Mockito.verify(connManager).releaseConnection(managedConn, null, 678L, TimeUnit.MILLISECONDS); Mockito.verify(managedConn, Mockito.never()).close(); Assert.assertNotNull(finalResponse); Assert.assertTrue(Proxy.isProxyClass(finalResponse.getClass())); } @Test public void testExecRequestConnectionRelease() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); // The entity is streaming response.setEntity(EntityBuilder.create() .setStream(new ByteArrayInputStream(new byte[]{})) .build()); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(managedConn.isStale()).thenReturn(Boolean.FALSE); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response); Mockito.when(reuseStrategy.keepAlive( Mockito.same(response), Mockito.any())).thenReturn(Boolean.FALSE); final CloseableHttpResponse finalResponse = minimalClientExec.execute( route, request, context, execAware); Mockito.verify(connManager).requestConnection(route, null); Mockito.verify(connRequest).get(0, TimeUnit.MILLISECONDS); Mockito.verify(requestExecutor, Mockito.times(1)).execute(request, managedConn, context); Mockito.verify(connManager, Mockito.never()).releaseConnection( Mockito.same(managedConn), Mockito.any(), Mockito.anyInt(), Mockito.any()); Mockito.verify(managedConn, Mockito.never()).close(); Assert.assertNotNull(finalResponse); Assert.assertTrue(Proxy.isProxyClass(finalResponse.getClass())); finalResponse.close(); Mockito.verify(connManager, Mockito.times(1)).releaseConnection( managedConn, null, 0, TimeUnit.MILLISECONDS); Mockito.verify(managedConn, Mockito.times(1)).shutdown(); } @Test public void testSocketTimeoutExistingConnection() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final RequestConfig config = RequestConfig.custom().setSocketTimeout(3000).build(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); context.setRequestConfig(config); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); Mockito.when(managedConn.isOpen()).thenReturn(true); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response); minimalClientExec.execute(route, request, context, execAware); Mockito.verify(managedConn).setSocketTimeout(3000); } @Test public void testSocketTimeoutReset() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(requestExecutor.execute( Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response); minimalClientExec.execute(route, request, context, execAware); Mockito.verify(managedConn, Mockito.never()).setSocketTimeout(Mockito.anyInt()); } @Test(expected=RequestAbortedException.class) public void testExecAbortedPriorToConnectionLease() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(managedConn.isOpen()).thenReturn(Boolean.FALSE); Mockito.when(execAware.isAborted()).thenReturn(Boolean.TRUE); try { minimalClientExec.execute(route, request, context, execAware); } catch (final IOException ex) { Mockito.verify(connRequest, Mockito.times(1)).cancel(); throw ex; } } @Test(expected=RequestAbortedException.class) public void testExecConnectionRequestFailed() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(connRequest.get(Mockito.anyInt(), Mockito.any())) .thenThrow(new ExecutionException("Opppsie", null)); minimalClientExec.execute(route, request, context, execAware); } @Test(expected=InterruptedIOException.class) public void testExecConnectionShutDown() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(requestExecutor.execute( Mockito.any(), Mockito.any(), Mockito.any())).thenThrow(new ConnectionShutdownException()); minimalClientExec.execute(route, request, context, execAware); } @Test(expected=RuntimeException.class) public void testExecRuntimeException() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(requestExecutor.execute( Mockito.any(), Mockito.any(), Mockito.any())).thenThrow(new RuntimeException("Ka-boom")); try { minimalClientExec.execute(route, request, context, execAware); } catch (final Exception ex) { Mockito.verify(connManager).releaseConnection(managedConn, null, 0, TimeUnit.MILLISECONDS); throw ex; } } @Test(expected=HttpException.class) public void testExecHttpException() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(requestExecutor.execute( Mockito.any(), Mockito.any(), Mockito.any())).thenThrow(new HttpException("Ka-boom")); try { minimalClientExec.execute(route, request, context, execAware); } catch (final Exception ex) { Mockito.verify(connManager).releaseConnection(managedConn, null, 0, TimeUnit.MILLISECONDS); throw ex; } } @Test(expected=IOException.class) public void testExecIOException() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); Mockito.when(requestExecutor.execute( Mockito.any(), Mockito.any(), Mockito.any())).thenThrow(new IOException("Ka-boom")); try { minimalClientExec.execute(route, request, context, execAware); } catch (final Exception ex) { Mockito.verify(connManager).releaseConnection(managedConn, null, 0, TimeUnit.MILLISECONDS); throw ex; } } @Test public void absoluteUriIsRewrittenToRelativeBeforeBeingPassedInRequestLine() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpClientContext context = new HttpClientContext(); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test")); final HttpResponse response = Mockito.mock(HttpResponse.class); Mockito.when(requestExecutor.execute( Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(response); minimalClientExec.execute(route, request, context, execAware); final ArgumentCaptor reqCaptor = ArgumentCaptor.forClass(HttpRequest.class); Mockito.verify(requestExecutor).execute(reqCaptor.capture(), Mockito.any(), Mockito.any()); assertEquals("/test", reqCaptor.getValue().getRequestLine().getUri()); } } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestProtocolExec.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestProtocolExec0100644 0000000 0000000 00000026643 12301751660 032542 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpProcessor; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.io.IOException; import java.net.URI; public class TestProtocolExec { @Mock private ClientExecChain requestExecutor; @Mock private HttpProcessor httpProcessor; @Mock private HttpExecutionAware execAware; private ProtocolExec protocolExec; private HttpHost target; private HttpHost proxy; @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); protocolExec = new ProtocolExec(requestExecutor, httpProcessor); target = new HttpHost("foo", 80); proxy = new HttpHost("bar", 8888); } @Test public void testFundamentals() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("/test")); final HttpClientContext context = HttpClientContext.create(); final CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(response); protocolExec.execute(route, request, context, execAware); Mockito.verify(httpProcessor).process(request, context); Mockito.verify(requestExecutor).execute(route, request, context, execAware); Mockito.verify(httpProcessor).process(response, context); Assert.assertEquals(new HttpHost("foo", 80), context.getTargetHost()); Assert.assertEquals(target, context.getTargetHost()); Assert.assertEquals(route, context.getHttpRoute()); Assert.assertSame(request, context.getRequest()); Assert.assertSame(response, context.getResponse()); } @Test public void testRewriteAbsoluteRequestURI() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpRequestWrapper request = HttpRequestWrapper.wrap( new HttpGet("http://foo/test")); protocolExec.rewriteRequestURI(request, route); Assert.assertEquals(new URI("/test"), request.getURI()); } @Test public void testRewriteEmptyRequestURI() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpRequestWrapper request = HttpRequestWrapper.wrap( new HttpGet("")); protocolExec.rewriteRequestURI(request, route); Assert.assertEquals(new URI("/"), request.getURI()); } @Test public void testRewriteAbsoluteRequestURIViaPRoxy() throws Exception { final HttpRoute route = new HttpRoute(target, proxy); final HttpRequestWrapper request = HttpRequestWrapper.wrap( new HttpGet("http://foo/test")); protocolExec.rewriteRequestURI(request, route); Assert.assertEquals(new URI("http://foo/test"), request.getURI()); } @Test public void testRewriteRelativeRequestURIViaPRoxy() throws Exception { final HttpRoute route = new HttpRoute(target, proxy); final HttpRequestWrapper request = HttpRequestWrapper.wrap( new HttpGet("/test")); protocolExec.rewriteRequestURI(request, route); Assert.assertEquals(new URI("http://foo:80/test"), request.getURI()); } @Test public void testHostHeaderUriRequest() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpRequestWrapper request = HttpRequestWrapper.wrap( new HttpGet("http://bar/test")); final HttpClientContext context = HttpClientContext.create(); protocolExec.execute(route, request, context, execAware); // ProtocolExect should have extracted the host from request URI Assert.assertEquals(new HttpHost("bar", -1, "http"), context.getTargetHost()); } @Test public void testHostHeaderWhenNonUriRequest() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpRequestWrapper request = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "http://bar/test")); final HttpClientContext context = HttpClientContext.create(); protocolExec.execute(route, request, context, execAware); // ProtocolExect should have extracted the host from request URI Assert.assertEquals(new HttpHost("bar", -1, "http"), context.getTargetHost()); } @Test public void testHostHeaderWhenNonUriRequestAndInvalidUri() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpRequestWrapper request = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "http://bar/test|")); final HttpClientContext context = HttpClientContext.create(); protocolExec.execute(route, request, context, execAware); // ProtocolExect should have fall back to physical host as request URI // is not parseable Assert.assertEquals(new HttpHost("foo", 80, "http"), context.getTargetHost()); } @Test public void testHostHeaderImplicitHost() throws Exception { final HttpRoute route = new HttpRoute(new HttpHost("somehost", 8080)); final HttpRequestWrapper request = HttpRequestWrapper.wrap( new HttpGet("/test")); final HttpClientContext context = HttpClientContext.create(); protocolExec.execute(route, request, context, execAware); Assert.assertEquals(new HttpHost("somehost", 8080), context.getTargetHost()); } @Test public void testUserInfoInRequestURI() throws Exception { final HttpRoute route = new HttpRoute(new HttpHost("somehost", 8080)); final HttpRequestWrapper request = HttpRequestWrapper.wrap( new HttpGet("http://somefella:secret@bar/test")); final HttpClientContext context = HttpClientContext.create(); protocolExec.execute(route, request, context, execAware); Assert.assertEquals(new URI("/test"), request.getURI()); Assert.assertEquals(new HttpHost("bar", -1), context.getTargetHost()); final CredentialsProvider credentialsProvider = context.getCredentialsProvider(); Assert.assertNotNull(credentialsProvider); final Credentials creds = credentialsProvider.getCredentials(new AuthScope("bar", -1, null)); Assert.assertNotNull(creds); Assert.assertEquals("somefella", creds.getUserPrincipal().getName()); } @Test(expected = HttpException.class) public void testPostProcessHttpException() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("/test")); final HttpClientContext context = HttpClientContext.create(); final CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(response); Mockito.doThrow(new HttpException("Ooopsie")).when(httpProcessor).process( Mockito.same(response), Mockito.any()); try { protocolExec.execute(route, request, context, execAware); } catch (final Exception ex) { Mockito.verify(response).close(); throw ex; } } @Test(expected = IOException.class) public void testPostProcessIOException() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("/test")); final HttpClientContext context = HttpClientContext.create(); final CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(response); Mockito.doThrow(new IOException("Ooopsie")).when(httpProcessor).process( Mockito.same(response), Mockito.any()); try { protocolExec.execute(route, request, context, execAware); } catch (final Exception ex) { Mockito.verify(response).close(); throw ex; } } @Test(expected = RuntimeException.class) public void testPostProcessRuntimeException() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("/test")); final HttpClientContext context = HttpClientContext.create(); final CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(response); Mockito.doThrow(new RuntimeException("Ooopsie")).when(httpProcessor).process( Mockito.same(response), Mockito.any()); try { protocolExec.execute(route, request, context, execAware); } catch (final Exception ex) { Mockito.verify(response).close(); throw ex; } } } ././@LongLink0100644 0000000 0000000 00000000152 12302131605 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestRedirectExec.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestRedirectExec0100644 0000000 0000000 00000041024 12301751660 032470 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import junit.framework.Assert; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.ProtocolException; import org.apache.http.auth.AuthProtocolState; import org.apache.http.auth.AuthState; import org.apache.http.auth.NTCredentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.RedirectException; import org.apache.http.client.RedirectStrategy; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.EntityBuilder; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.auth.NTLMScheme; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.List; public class TestRedirectExec { @Mock private ClientExecChain requestExecutor; @Mock private HttpRoutePlanner httpRoutePlanner; @Mock private RedirectStrategy redirectStrategy; @Mock private HttpExecutionAware execAware; private RedirectExec redirectExec; private HttpHost target; @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); redirectExec = new RedirectExec(requestExecutor, httpRoutePlanner, redirectStrategy); target = new HttpHost("localhost", 80); } @Test public void testFundamentals() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpGet get = new HttpGet("/test"); get.addHeader("header", "this"); get.addHeader("header", "that"); final HttpRequestWrapper request = HttpRequestWrapper.wrap(get); final HttpClientContext context = HttpClientContext.create(); final CloseableHttpResponse response1 = Mockito.mock(CloseableHttpResponse.class); final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3})); final HttpEntity entity1 = EntityBuilder.create() .setStream(instream1) .build(); Mockito.when(response1.getEntity()).thenReturn(entity1); final CloseableHttpResponse response2 = Mockito.mock(CloseableHttpResponse.class); final InputStream instream2 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3})); final HttpEntity entity2 = EntityBuilder.create() .setStream(instream2) .build(); Mockito.when(response2.getEntity()).thenReturn(entity2); final HttpGet redirect = new HttpGet("http://localhost:80/redirect"); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response1); Mockito.when(requestExecutor.execute( Mockito.eq(route), HttpRequestWrapperMatcher.same(redirect), Mockito.any(), Mockito.any())).thenReturn(response2); Mockito.when(redirectStrategy.isRedirected( Mockito.same(request), Mockito.same(response1), Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(redirectStrategy.getRedirect( Mockito.same(request), Mockito.same(response1), Mockito.any())).thenReturn(redirect); Mockito.when(httpRoutePlanner.determineRoute( Mockito.eq(target), Mockito.any(), Mockito.any())).thenReturn(route); redirectExec.execute(route, request, context, execAware); final ArgumentCaptor reqCaptor = ArgumentCaptor.forClass( HttpRequestWrapper.class); Mockito.verify(requestExecutor, Mockito.times(2)).execute( Mockito.eq(route), reqCaptor.capture(), Mockito.same(context), Mockito.same(execAware)); final List allValues = reqCaptor.getAllValues(); Assert.assertNotNull(allValues); Assert.assertEquals(2, allValues.size()); Assert.assertSame(request, allValues.get(0)); final HttpRequestWrapper redirectWrapper = allValues.get(1); final Header[] headers = redirectWrapper.getHeaders("header"); Assert.assertNotNull(headers); Assert.assertEquals(2, headers.length); Assert.assertEquals("this", headers[0].getValue()); Assert.assertEquals("that", headers[1].getValue()); Mockito.verify(response1, Mockito.times(1)).close(); Mockito.verify(instream1, Mockito.times(1)).close(); Mockito.verify(response2, Mockito.never()).close(); Mockito.verify(instream2, Mockito.never()).close(); } @Test(expected = RedirectException.class) public void testMaxRedirect() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpGet get = new HttpGet("/test"); final HttpRequestWrapper request = HttpRequestWrapper.wrap(get); final HttpClientContext context = HttpClientContext.create(); final RequestConfig config = RequestConfig.custom() .setRedirectsEnabled(true) .setMaxRedirects(3) .build(); context.setRequestConfig(config); final CloseableHttpResponse response1 = Mockito.mock(CloseableHttpResponse.class); final HttpGet redirect = new HttpGet("http://localhost:80/redirect"); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(response1); Mockito.when(redirectStrategy.isRedirected( Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(redirectStrategy.getRedirect( Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(redirect); Mockito.when(httpRoutePlanner.determineRoute( Mockito.eq(target), Mockito.any(), Mockito.any())).thenReturn(route); redirectExec.execute(route, request, context, execAware); } @Test(expected = HttpException.class) public void testRelativeRedirect() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpGet get = new HttpGet("/test"); final HttpRequestWrapper request = HttpRequestWrapper.wrap(get); final HttpClientContext context = HttpClientContext.create(); final CloseableHttpResponse response1 = Mockito.mock(CloseableHttpResponse.class); final CloseableHttpResponse response2 = Mockito.mock(CloseableHttpResponse.class); final HttpGet redirect = new HttpGet("/redirect"); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response1); Mockito.when(requestExecutor.execute( Mockito.eq(route), HttpRequestWrapperMatcher.same(redirect), Mockito.any(), Mockito.any())).thenReturn(response2); Mockito.when(redirectStrategy.isRedirected( Mockito.same(request), Mockito.same(response1), Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(redirectStrategy.getRedirect( Mockito.same(request), Mockito.same(response1), Mockito.any())).thenReturn(redirect); Mockito.when(httpRoutePlanner.determineRoute( Mockito.eq(target), Mockito.any(), Mockito.any())).thenReturn(route); redirectExec.execute(route, request, context, execAware); } @Test public void testCrossSiteRedirect() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpGet get = new HttpGet("/test"); final HttpRequestWrapper request = HttpRequestWrapper.wrap(get); final HttpClientContext context = HttpClientContext.create(); final AuthState targetAuthState = new AuthState(); targetAuthState.setState(AuthProtocolState.SUCCESS); targetAuthState.update(new BasicScheme(), new UsernamePasswordCredentials("user:pass")); final AuthState proxyAuthState = new AuthState(); proxyAuthState.setState(AuthProtocolState.SUCCESS); proxyAuthState.update(new NTLMScheme(), new NTCredentials("user:pass")); context.setAttribute(HttpClientContext.TARGET_AUTH_STATE, targetAuthState); context.setAttribute(HttpClientContext.PROXY_AUTH_STATE, proxyAuthState); final CloseableHttpResponse response1 = Mockito.mock(CloseableHttpResponse.class); final CloseableHttpResponse response2 = Mockito.mock(CloseableHttpResponse.class); final HttpGet redirect = new HttpGet("http://otherhost/redirect"); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response1); Mockito.when(requestExecutor.execute( Mockito.eq(route), HttpRequestWrapperMatcher.same(redirect), Mockito.any(), Mockito.any())).thenReturn(response2); Mockito.when(redirectStrategy.isRedirected( Mockito.same(request), Mockito.same(response1), Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(redirectStrategy.getRedirect( Mockito.same(request), Mockito.same(response1), Mockito.any())).thenReturn(redirect); Mockito.when(httpRoutePlanner.determineRoute( Mockito.eq(target), Mockito.any(), Mockito.any())).thenReturn(new HttpRoute(new HttpHost("otherhost"))); redirectExec.execute(route, request, context, execAware); Assert.assertNotNull(context.getTargetAuthState()); Assert.assertEquals(AuthProtocolState.UNCHALLENGED, context.getTargetAuthState().getState()); Assert.assertEquals(null, context.getTargetAuthState().getAuthScheme()); Assert.assertNotNull(context.getProxyAuthState()); Assert.assertEquals(AuthProtocolState.UNCHALLENGED, context.getProxyAuthState().getState()); Assert.assertEquals(null, context.getProxyAuthState().getAuthScheme()); } @Test(expected = RuntimeException.class) public void testRedirectRuntimeException() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpGet get = new HttpGet("/test"); final HttpRequestWrapper request = HttpRequestWrapper.wrap(get); final HttpClientContext context = HttpClientContext.create(); final CloseableHttpResponse response1 = Mockito.mock(CloseableHttpResponse.class); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response1); Mockito.when(redirectStrategy.isRedirected( Mockito.same(request), Mockito.same(response1), Mockito.any())).thenReturn(Boolean.TRUE); Mockito.doThrow(new RuntimeException("Oppsie")).when(redirectStrategy.getRedirect( Mockito.same(request), Mockito.same(response1), Mockito.any())); try { redirectExec.execute(route, request, context, execAware); } catch (final Exception ex) { Mockito.verify(response1).close(); throw ex; } } @Test(expected = ProtocolException.class) public void testRedirectProtocolException() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpGet get = new HttpGet("/test"); final HttpRequestWrapper request = HttpRequestWrapper.wrap(get); final HttpClientContext context = HttpClientContext.create(); final CloseableHttpResponse response1 = Mockito.mock(CloseableHttpResponse.class); final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3})); final HttpEntity entity1 = EntityBuilder.create() .setStream(instream1) .build(); Mockito.when(response1.getEntity()).thenReturn(entity1); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response1); Mockito.when(redirectStrategy.isRedirected( Mockito.same(request), Mockito.same(response1), Mockito.any())).thenReturn(Boolean.TRUE); Mockito.doThrow(new ProtocolException("Oppsie")).when(redirectStrategy).getRedirect( Mockito.same(request), Mockito.same(response1), Mockito.any()); try { redirectExec.execute(route, request, context, execAware); } catch (final Exception ex) { Mockito.verify(instream1).close(); Mockito.verify(response1).close(); throw ex; } } static class HttpRequestWrapperMatcher extends ArgumentMatcher { private final HttpRequest original; HttpRequestWrapperMatcher(final HttpRequest original) { super(); this.original = original; } @Override public boolean matches(final Object obj) { final HttpRequestWrapper wrapper = (HttpRequestWrapper) obj; return original == wrapper.getOriginal(); } static HttpRequestWrapper same(final HttpRequest original) { return Matchers.argThat(new HttpRequestWrapperMatcher(original)); } } } ././@LongLink0100644 0000000 0000000 00000000163 12302131605 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestResponseEntityWrapper.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestResponseEnti0100644 0000000 0000000 00000012510 12301751660 032536 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.SocketException; import org.apache.http.HttpEntity; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; public class TestResponseEntityWrapper { private InputStream instream; private HttpEntity entity; private ConnectionHolder connHolder; private ResponseEntityWrapper wrapper; @Before public void setup() throws Exception { instream = Mockito.mock(InputStream.class); entity = Mockito.mock(HttpEntity.class); Mockito.when(entity.getContent()).thenReturn(instream); connHolder = Mockito.mock(ConnectionHolder.class); wrapper = new ResponseEntityWrapper(entity, connHolder); } @Test public void testReusableEntityStreamClosed() throws Exception { Mockito.when(entity.isStreaming()).thenReturn(true); Mockito.when(connHolder.isReusable()).thenReturn(true); EntityUtils.consume(wrapper); Mockito.verify(instream, Mockito.times(1)).close(); Mockito.verify(connHolder).releaseConnection(); } @Test public void testReusableEntityStreamClosedIOError() throws Exception { Mockito.when(entity.isStreaming()).thenReturn(true); Mockito.when(connHolder.isReusable()).thenReturn(true); Mockito.doThrow(new IOException()).when(instream).close(); try { EntityUtils.consume(wrapper); Assert.fail("IOException expected"); } catch (final IOException ex) { } Mockito.verify(connHolder).abortConnection(); } @Test public void testEntityStreamClosedIOErrorAlreadyReleased() throws Exception { Mockito.when(entity.isStreaming()).thenReturn(true); Mockito.when(connHolder.isReusable()).thenReturn(true); Mockito.when(connHolder.isReleased()).thenReturn(true); Mockito.doThrow(new SocketException()).when(instream).close(); EntityUtils.consume(wrapper); Mockito.verify(connHolder).abortConnection(); } @Test public void testReusableEntityWriteTo() throws Exception { final OutputStream outstream = Mockito.mock(OutputStream.class); Mockito.when(entity.isStreaming()).thenReturn(true); Mockito.when(connHolder.isReusable()).thenReturn(true); wrapper.writeTo(outstream); Mockito.verify(connHolder).releaseConnection(); } @Test public void testReusableEntityWriteToIOError() throws Exception { final OutputStream outstream = Mockito.mock(OutputStream.class); Mockito.when(entity.isStreaming()).thenReturn(true); Mockito.when(connHolder.isReusable()).thenReturn(true); Mockito.doThrow(new IOException()).when(entity).writeTo(outstream); try { wrapper.writeTo(outstream); Assert.fail("IOException expected"); } catch (final IOException ex) { } Mockito.verify(connHolder, Mockito.never()).releaseConnection(); Mockito.verify(connHolder).abortConnection(); } @Test public void testReusableEntityEndOfStream() throws Exception { Mockito.when(instream.read()).thenReturn(-1); Mockito.when(entity.isStreaming()).thenReturn(true); Mockito.when(connHolder.isReusable()).thenReturn(true); final InputStream content = wrapper.getContent(); Assert.assertEquals(-1, content.read()); Mockito.verify(instream).close(); Mockito.verify(connHolder).releaseConnection(); } @Test public void testReusableEntityEndOfStreamIOError() throws Exception { Mockito.when(instream.read()).thenReturn(-1); Mockito.when(entity.isStreaming()).thenReturn(true); Mockito.when(connHolder.isReusable()).thenReturn(true); Mockito.doThrow(new IOException()).when(instream).close(); final InputStream content = wrapper.getContent(); try { content.read(); Assert.fail("IOException expected"); } catch (final IOException ex) { } Mockito.verify(connHolder).abortConnection(); } } ././@LongLink0100644 0000000 0000000 00000000147 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestRetryExec.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestRetryExec.ja0100644 0000000 0000000 00000017017 12301751660 032432 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import junit.framework.Assert; import org.apache.http.Header; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpHost; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.NonRepeatableRequestException; import org.apache.http.client.entity.EntityBuilder; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.protocol.HttpContext; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; public class TestRetryExec { @Mock private ClientExecChain requestExecutor; @Mock private HttpRequestRetryHandler retryHandler; @Mock private HttpExecutionAware execAware; private RetryExec retryExec; private HttpHost target; @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); retryExec = new RetryExec(requestExecutor, retryHandler); target = new HttpHost("localhost", 80); } @Test(expected = IOException.class) public void testFundamentals() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpGet get = new HttpGet("/test"); get.addHeader("header", "this"); get.addHeader("header", "that"); final HttpRequestWrapper request = HttpRequestWrapper.wrap(get); final HttpClientContext context = HttpClientContext.create(); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.same(request), Mockito.any(), Mockito.any())).thenAnswer(new Answer() { public Object answer(final InvocationOnMock invocationOnMock) throws Throwable { final Object[] args = invocationOnMock.getArguments(); final HttpRequestWrapper wrapper = (HttpRequestWrapper) args[1]; final Header[] headers = wrapper.getAllHeaders(); Assert.assertEquals(2, headers.length); Assert.assertEquals("this", headers[0].getValue()); Assert.assertEquals("that", headers[1].getValue()); wrapper.addHeader("Cookie", "monster"); throw new IOException("Ka-boom"); } }); Mockito.when(retryHandler.retryRequest( Mockito.any(), Mockito.eq(1), Mockito.any())).thenReturn(Boolean.TRUE); try { retryExec.execute(route, request, context, execAware); } catch (final IOException ex) { Mockito.verify(requestExecutor, Mockito.times(2)).execute( Mockito.eq(route), Mockito.same(request), Mockito.same(context), Mockito.same(execAware)); throw ex; } } @Test(expected = IOException.class) public void testAbortedRequest() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpGet get = new HttpGet("/test"); final HttpRequestWrapper request = HttpRequestWrapper.wrap(get); final HttpClientContext context = HttpClientContext.create(); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.same(request), Mockito.any(), Mockito.any())).thenThrow(new IOException("Ka-boom")); Mockito.when(execAware.isAborted()).thenReturn(Boolean.TRUE); try { retryExec.execute(route, request, context, execAware); } catch (final IOException ex) { Mockito.verify(requestExecutor, Mockito.times(1)).execute( Mockito.eq(route), Mockito.same(request), Mockito.same(context), Mockito.same(execAware)); Mockito.verify(retryHandler, Mockito.never()).retryRequest( Mockito.any(), Mockito.anyInt(), Mockito.any()); throw ex; } } @Test(expected = NonRepeatableRequestException.class) public void testNonRepeatableRequest() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpPost post = new HttpPost("/test"); post.setEntity(EntityBuilder.create() .setStream(new ByteArrayInputStream(new byte[]{})) .build()); final HttpRequestWrapper request = HttpRequestWrapper.wrap(post); final HttpClientContext context = HttpClientContext.create(); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.same(request), Mockito.any(), Mockito.any())).thenAnswer(new Answer() { public Object answer(final InvocationOnMock invocationOnMock) throws Throwable { final Object[] args = invocationOnMock.getArguments(); final HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest) args[1]; request.getEntity().writeTo(new ByteArrayOutputStream()); throw new IOException("Ka-boom"); } }); Mockito.when(retryHandler.retryRequest( Mockito.any(), Mockito.eq(1), Mockito.any())).thenReturn(Boolean.TRUE); try { retryExec.execute(route, request, context, execAware); } catch (final IOException ex) { Mockito.verify(requestExecutor, Mockito.times(1)).execute( Mockito.eq(route), Mockito.same(request), Mockito.same(context), Mockito.same(execAware)); throw ex; } } } ././@LongLink0100644 0000000 0000000 00000000171 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestServiceUnavailableRetryExec.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/impl/execchain/TestServiceUnava0100644 0000000 0000000 00000011277 12301751660 032524 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.execchain; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.client.ServiceUnavailableRetryStrategy; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.protocol.HttpContext; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; public class TestServiceUnavailableRetryExec { @Mock private ClientExecChain requestExecutor; @Mock private ServiceUnavailableRetryStrategy retryStrategy; @Mock private HttpExecutionAware execAware; private ServiceUnavailableRetryExec retryExec; private HttpHost target; @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); retryExec = new ServiceUnavailableRetryExec(requestExecutor, retryStrategy); target = new HttpHost("localhost", 80); } @Test public void testFundamentals() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpGet get = new HttpGet("/test"); final HttpRequestWrapper request = HttpRequestWrapper.wrap(get); final HttpClientContext context = HttpClientContext.create(); final CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.same(request), Mockito.any(), Mockito.any())).thenReturn(response); Mockito.when(retryStrategy.retryRequest( Mockito.any(), Mockito.anyInt(), Mockito.any())).thenReturn(Boolean.TRUE, Boolean.FALSE); Mockito.when(retryStrategy.getRetryInterval()).thenReturn(0L); retryExec.execute(route, request, context, execAware); Mockito.verify(requestExecutor, Mockito.times(2)).execute( Mockito.eq(route), Mockito.same(request), Mockito.same(context), Mockito.same(execAware)); Mockito.verify(response, Mockito.times(1)).close(); } @Test(expected = RuntimeException.class) public void testStrategyRuntimeException() throws Exception { final HttpRoute route = new HttpRoute(target); final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("/test")); final HttpClientContext context = HttpClientContext.create(); final CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class); Mockito.when(requestExecutor.execute( Mockito.eq(route), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(response); Mockito.doThrow(new RuntimeException("Ooopsie")).when(retryStrategy).retryRequest( Mockito.any(), Mockito.anyInt(), Mockito.any()); try { retryExec.execute(route, request, context, execAware); } catch (final Exception ex) { Mockito.verify(response).close(); throw ex; } } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/localserver/0040755 0000000 0000000 00000000000 12301751660 026772 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000156 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/localserver/BasicAuthTokenExtractor.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/localserver/BasicAuthTokenExtra0100644 0000000 0000000 00000005343 12301751660 032567 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.localserver; import org.apache.commons.codec.BinaryDecoder; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Base64; import org.apache.http.Header; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.ProtocolException; import org.apache.http.auth.AUTH; import org.apache.http.util.EncodingUtils; public class BasicAuthTokenExtractor { public String extract(final HttpRequest request) throws HttpException { String auth = null; final Header h = request.getFirstHeader(AUTH.WWW_AUTH_RESP); if (h != null) { final String s = h.getValue(); if (s != null) { auth = s.trim(); } } if (auth != null) { final int i = auth.indexOf(' '); if (i == -1) { throw new ProtocolException("Invalid Authorization header: " + auth); } final String authscheme = auth.substring(0, i); if (authscheme.equalsIgnoreCase("basic")) { final String s = auth.substring(i + 1).trim(); try { final byte[] credsRaw = EncodingUtils.getAsciiBytes(s); final BinaryDecoder codec = new Base64(); auth = EncodingUtils.getAsciiString(codec.decode(credsRaw)); } catch (final DecoderException ex) { throw new ProtocolException("Malformed BASIC credentials"); } } } return auth; } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/localserver/EchoHandler.java0100644 0000000 0000000 00000007154 12301751660 032015 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.localserver; import java.io.IOException; import java.util.Locale; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.MethodNotSupportedException; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.util.EntityUtils; /** * A handler that echos the incoming request entity. * * * * */ public class EchoHandler implements HttpRequestHandler { // public default constructor /** * Handles a request by echoing the incoming request entity. * If there is no request entity, an empty document is returned. * * @param request the request * @param response the response * @param context the context * * @throws HttpException in case of a problem * @throws IOException in case of an IO problem */ public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final String method = request.getRequestLine().getMethod().toUpperCase(Locale.ENGLISH); if (!"GET".equals(method) && !"POST".equals(method) && !"PUT".equals(method) ) { throw new MethodNotSupportedException (method + " not supported by " + getClass().getName()); } HttpEntity entity = null; if (request instanceof HttpEntityEnclosingRequest) { entity = ((HttpEntityEnclosingRequest)request).getEntity(); } // For some reason, just putting the incoming entity into // the response will not work. We have to buffer the message. byte[] data; if (entity == null) { data = new byte [0]; } else { data = EntityUtils.toByteArray(entity); } final ByteArrayEntity bae = new ByteArrayEntity(data); if (entity != null) { bae.setContentType(entity.getContentType()); } entity = bae; response.setStatusCode(HttpStatus.SC_OK); response.setEntity(entity); } // handle } // class EchoHandler ././@LongLink0100644 0000000 0000000 00000000152 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/localserver/LocalServerTestBase.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/localserver/LocalServerTestBase0100644 0000000 0000000 00000004551 12301751660 032573 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.localserver; import java.net.InetSocketAddress; import org.apache.http.HttpHost; import org.junit.After; /** * Base class for tests using {@link LocalTestServer}. The server will not be started * per default. */ public abstract class LocalServerTestBase { /** The local server for testing. */ protected LocalTestServer localServer; @After public void shutDownServer() throws Exception { if (localServer != null) { localServer.stop(); } localServer = null; } protected void startServer() throws Exception { if (localServer == null) { localServer = new LocalTestServer(null, null); localServer.registerDefaultHandlers(); } localServer.setTimeout(5000); localServer.start(); } /** * Obtains the address of the local test server. * * @return the test server host, with a scheme name of "http" */ protected HttpHost getServerHttp() { final InetSocketAddress address = localServer.getServiceAddress(); return new HttpHost( address.getHostName(), address.getPort(), "http"); } } ././@LongLink0100644 0000000 0000000 00000000146 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/localserver/LocalTestServer.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/localserver/LocalTestServer.jav0100644 0000000 0000000 00000033355 12301751660 032563 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.localserver; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; import org.apache.http.ConnectionReuseStrategy; import org.apache.http.HttpResponseFactory; import org.apache.http.HttpResponseInterceptor; import org.apache.http.HttpServerConnection; import org.apache.http.impl.DefaultBHttpServerConnection; import org.apache.http.impl.DefaultConnectionReuseStrategy; import org.apache.http.impl.DefaultHttpResponseFactory; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpExpectationVerifier; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.protocol.HttpService; import org.apache.http.protocol.ImmutableHttpProcessor; import org.apache.http.protocol.ResponseConnControl; import org.apache.http.protocol.ResponseContent; import org.apache.http.protocol.ResponseDate; import org.apache.http.protocol.ResponseServer; import org.apache.http.protocol.UriHttpRequestHandlerMapper; import org.apache.http.util.Asserts; /** * Local HTTP server for tests that require one. * Based on the ElementalHttpServer example in HttpCore. */ public class LocalTestServer { public final static String ORIGIN = "LocalTestServer/1.1"; /** * The local address to bind to. * The host is an IP number rather than "localhost" to avoid surprises * on hosts that map "localhost" to an IPv6 address or something else. * The port is 0 to let the system pick one. */ public final static InetSocketAddress TEST_SERVER_ADDR = new InetSocketAddress("127.0.0.1", 0); /** The request handler registry. */ private final UriHttpRequestHandlerMapper handlerRegistry; private final HttpService httpservice; /** Optional SSL context */ private final SSLContext sslcontext; /** Optional flag whether to force SSL context */ private final boolean forceSSLAuth; /** The server socket, while being served. */ private volatile ServerSocket servicedSocket; /** The request listening thread, while listening. */ private volatile ListenerThread listenerThread; /** Set of active worker threads */ private final Set workers; /** The number of connections this accepted. */ private final AtomicInteger acceptedConnections = new AtomicInteger(0); private volatile int timeout; /** * Creates a new test server. * * @param proc the HTTP processors to be used by the server, or * null to use a * {@link #newProcessor default} processor * @param reuseStrat the connection reuse strategy to be used by the * server, or null to use * {@link #newConnectionReuseStrategy() default} * strategy. * @param responseFactory the response factory to be used by the * server, or null to use * {@link #newHttpResponseFactory() default} factory. * @param expectationVerifier the expectation verifier. May be * null. * @param sslcontext optional SSL context if the server is to leverage * SSL/TLS transport security * @param forceSSLAuth whether or not the server needs to enforce client auth */ public LocalTestServer( final HttpProcessor proc, final ConnectionReuseStrategy reuseStrat, final HttpResponseFactory responseFactory, final HttpExpectationVerifier expectationVerifier, final SSLContext sslcontext, final boolean forceSSLAuth) { super(); this.handlerRegistry = new UriHttpRequestHandlerMapper(); this.workers = Collections.synchronizedSet(new HashSet()); this.httpservice = new HttpService( proc != null ? proc : newProcessor(), reuseStrat != null ? reuseStrat: newConnectionReuseStrategy(), responseFactory != null ? responseFactory: newHttpResponseFactory(), handlerRegistry, expectationVerifier); this.sslcontext = sslcontext; this.forceSSLAuth = forceSSLAuth; } public LocalTestServer( final HttpProcessor proc, final ConnectionReuseStrategy reuseStrat) { this(proc, reuseStrat, null, null, null, false); } /** * Creates a new test server with SSL/TLS encryption. * * @param sslcontext SSL context * @param forceSSLAuth whether or not the server needs to enforce client auth */ public LocalTestServer(final SSLContext sslcontext, final boolean forceSSLAuth) { this(null, null, null, null, sslcontext, forceSSLAuth); } /** * Creates a new test server with SSL/TLS encryption. * * @param sslcontext SSL context */ public LocalTestServer(final SSLContext sslcontext) { this(null, null, null, null, sslcontext, false); } /** * Obtains an HTTP protocol processor with default interceptors. * * @return a protocol processor for server-side use */ protected HttpProcessor newProcessor() { return new ImmutableHttpProcessor( new HttpResponseInterceptor[] { new ResponseDate(), new ResponseServer(ORIGIN), new ResponseContent(), new ResponseConnControl() }); } protected ConnectionReuseStrategy newConnectionReuseStrategy() { return DefaultConnectionReuseStrategy.INSTANCE; } protected HttpResponseFactory newHttpResponseFactory() { return DefaultHttpResponseFactory.INSTANCE; } /** * Returns the number of connections this test server has accepted. */ public int getAcceptedConnectionCount() { return acceptedConnections.get(); } /** * {@link #register Registers} a set of default request handlers. *
     * URI pattern      Handler
     * -----------      -------
     * /echo/*          {@link EchoHandler EchoHandler}
     * /random/*        {@link RandomHandler RandomHandler}
     * 
*/ public void registerDefaultHandlers() { handlerRegistry.register("/echo/*", new EchoHandler()); handlerRegistry.register("/random/*", new RandomHandler()); } /** * Registers a handler with the local registry. * * @param pattern the URL pattern to match * @param handler the handler to apply */ public void register(final String pattern, final HttpRequestHandler handler) { handlerRegistry.register(pattern, handler); } /** * Unregisters a handler from the local registry. * * @param pattern the URL pattern */ public void unregister(final String pattern) { handlerRegistry.unregister(pattern); } public int getTimeout() { return timeout; } public void setTimeout(final int timeout) { this.timeout = timeout; } /** * Starts this test server. */ public void start() throws Exception { Asserts.check(servicedSocket == null, "Already running"); final ServerSocket ssock; if (sslcontext != null) { final SSLServerSocketFactory sf = sslcontext.getServerSocketFactory(); final SSLServerSocket sslsock = (SSLServerSocket) sf.createServerSocket(); if (forceSSLAuth) { sslsock.setNeedClientAuth(true); } else { sslsock.setWantClientAuth(true); } ssock = sslsock; } else { ssock = new ServerSocket(); } ssock.setReuseAddress(true); // probably pointless for port '0' ssock.bind(TEST_SERVER_ADDR); servicedSocket = ssock; listenerThread = new ListenerThread(); listenerThread.setDaemon(false); listenerThread.start(); } /** * Stops this test server. */ public void stop() throws Exception { if (servicedSocket == null) { return; // not running } final ListenerThread t = listenerThread; if (t != null) { t.shutdown(); } synchronized (workers) { for (final Worker worker : workers) { worker.shutdown(); } } } public void awaitTermination(final long timeMs) throws InterruptedException { if (listenerThread != null) { listenerThread.join(timeMs); } } @Override public String toString() { final ServerSocket ssock = servicedSocket; // avoid synchronization final StringBuilder sb = new StringBuilder(80); sb.append("LocalTestServer/"); if (ssock == null) { sb.append("stopped"); } else { sb.append(ssock.getLocalSocketAddress()); } return sb.toString(); } /** * Obtains the local address the server is listening on * * @return the service address */ public InetSocketAddress getServiceAddress() { final ServerSocket ssock = servicedSocket; // avoid synchronization Asserts.check(ssock != null, "Not running"); return (InetSocketAddress) ssock.getLocalSocketAddress(); } /** * Creates an instance of {@link DefaultBHttpServerConnection} to be used * in the Worker thread. *

* This method can be overridden in a super class in order to provide * a different implementation of the {@link DefaultBHttpServerConnection}. * * @return DefaultBHttpServerConnection. */ protected DefaultBHttpServerConnection createHttpServerConnection() { return new DefaultBHttpServerConnection(8 * 1024); } /** * The request listener. * Accepts incoming connections and launches a service thread. */ class ListenerThread extends Thread { private volatile Exception exception; ListenerThread() { super(); } @Override public void run() { try { while (!interrupted()) { final Socket socket = servicedSocket.accept(); acceptedConnections.incrementAndGet(); final DefaultBHttpServerConnection conn = createHttpServerConnection(); conn.bind(socket); conn.setSocketTimeout(timeout); // Start worker thread final Worker worker = new Worker(conn); workers.add(worker); worker.setDaemon(true); worker.start(); } } catch (final Exception ex) { this.exception = ex; } finally { try { servicedSocket.close(); } catch (final IOException ignore) { } } } public void shutdown() { interrupt(); try { servicedSocket.close(); } catch (final IOException ignore) { } } public Exception getException() { return this.exception; } } class Worker extends Thread { private final HttpServerConnection conn; private volatile Exception exception; public Worker(final HttpServerConnection conn) { this.conn = conn; } @Override public void run() { final HttpContext context = new BasicHttpContext(); try { while (this.conn.isOpen() && !Thread.interrupted()) { httpservice.handleRequest(this.conn, context); } } catch (final Exception ex) { this.exception = ex; } finally { workers.remove(this); try { this.conn.shutdown(); } catch (final IOException ignore) { } } } public void shutdown() { interrupt(); try { this.conn.shutdown(); } catch (final IOException ignore) { } } public Exception getException() { return this.exception; } } } httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/localserver/RandomHandler.java0100644 0000000 0000000 00000017307 12301751660 032360 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.localserver; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.Locale; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.MethodNotSupportedException; import org.apache.http.entity.AbstractHttpEntity; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; /** * A handler that generates random data. * * * * */ public class RandomHandler implements HttpRequestHandler { // public default constructor /** * Handles a request by generating random data. * The length of the response can be specified in the request URI * as a number after the last /. For example /random/whatever/20 * will generate 20 random bytes in the printable ASCII range. * If the request URI ends with /, a random number of random bytes * is generated, but at least one. * * @param request the request * @param response the response * @param context the context * * @throws HttpException in case of a problem * @throws IOException in case of an IO problem */ public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final String method = request.getRequestLine().getMethod().toUpperCase(Locale.ENGLISH); if (!"GET".equals(method) && !"HEAD".equals(method)) { throw new MethodNotSupportedException (method + " not supported by " + getClass().getName()); } final String uri = request.getRequestLine().getUri(); final int slash = uri.lastIndexOf('/'); int length = -1; if (slash < uri.length()-1) { try { // no more than Integer, 2 GB ought to be enough for anybody length = Integer.parseInt(uri.substring(slash+1)); if (length < 0) { response.setStatusCode(HttpStatus.SC_BAD_REQUEST); response.setReasonPhrase("LENGTH " + length); } } catch (final NumberFormatException nfx) { response.setStatusCode(HttpStatus.SC_BAD_REQUEST); response.setReasonPhrase(nfx.toString()); } } else { // random length, but make sure at least something is sent length = 1 + (int)(Math.random() * 79.0); } if (length >= 0) { response.setStatusCode(HttpStatus.SC_OK); if (!"HEAD".equals(method)) { final RandomEntity entity = new RandomEntity(length); entity.setContentType("text/plain; charset=US-ASCII"); response.setEntity(entity); } else { response.setHeader("Content-Type", "text/plain; charset=US-ASCII"); response.setHeader("Content-Length", String.valueOf(length)); } } } // handle /** * An entity that generates random data. * This is an outgoing entity, it supports {@link #writeTo writeTo} * but not {@link #getContent getContent}. */ public static class RandomEntity extends AbstractHttpEntity { /** The range from which to generate random data. */ private final static byte[] RANGE; static { byte[] range = null; try { range = ("abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" ).getBytes("US-ASCII"); } catch (final UnsupportedEncodingException uex) { // never, US-ASCII is guaranteed } RANGE = range; } /** The length of the random data to generate. */ protected final long length; /** * Creates a new entity generating the given amount of data. * * @param len the number of random bytes to generate, * 0 to maxint */ public RandomEntity(final long len) { length = len; } /** * Tells that this entity is not streaming. * * @return false */ public final boolean isStreaming() { return false; } /** * Tells that this entity is repeatable, in a way. * Repetitions will generate different random data, * unless perchance the same random data is generated twice. * * @return true */ public boolean isRepeatable() { return true; } /** * Obtains the size of the random data. * * @return the number of random bytes to generate */ public long getContentLength() { return length; } /** * Not supported. * This method throws an exception. * * @return never anything */ public InputStream getContent() { throw new UnsupportedOperationException(); } /** * Generates the random content. * * @param out where to write the content to */ public void writeTo(final OutputStream out) throws IOException { final int blocksize = 2048; int remaining = (int) length; // range checked in constructor final byte[] data = new byte[Math.min(remaining, blocksize)]; while (remaining > 0) { final int end = Math.min(remaining, data.length); double value = 0.0; for (int i = 0; i < end; i++) { // we get 5 random characters out of one random value if (i%5 == 0) { value = Math.random(); } value = value * RANGE.length; final int d = (int) value; value = value - d; data[i] = RANGE[d]; } out.write(data, 0, end); out.flush(); remaining = remaining - end; } out.close(); } // writeTo } // class RandomEntity } // class RandomHandler ././@LongLink0100644 0000000 0000000 00000000147 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/localserver/RequestBasicAuth.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/localserver/RequestBasicAuth.ja0100644 0000000 0000000 00000003553 12301751660 032525 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.localserver; import java.io.IOException; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.protocol.HttpContext; public class RequestBasicAuth implements HttpRequestInterceptor { private final BasicAuthTokenExtractor authTokenExtractor; public RequestBasicAuth() { super(); this.authTokenExtractor = new BasicAuthTokenExtractor(); } public void process( final HttpRequest request, final HttpContext context) throws HttpException, IOException { context.setAttribute("creds", this.authTokenExtractor.extract(request)); } } ././@LongLink0100644 0000000 0000000 00000000160 12302131606 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/localserver/ResponseBasicUnauthorized.javahttpcomponents-client-4.3.3/httpclient/src/test/java/org/apache/http/localserver/ResponseBasicUnauth0100644 0000000 0000000 00000003542 12301751660 032643 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.localserver; import java.io.IOException; import org.apache.http.HttpException; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseInterceptor; import org.apache.http.HttpStatus; import org.apache.http.auth.AUTH; import org.apache.http.protocol.HttpContext; public class ResponseBasicUnauthorized implements HttpResponseInterceptor { public void process( final HttpResponse response, final HttpContext context) throws HttpException, IOException { if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { response.addHeader(AUTH.WWW_AUTH, "Basic realm=\"test realm\""); } } } httpcomponents-client-4.3.3/httpclient/src/test/resources/0040755 0000000 0000000 00000000000 12301751660 022553 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient/src/test/resources/commons-logging.properties0100644 0000000 0000000 00000002350 12301751660 027765 0ustar000000000 0000000 # ==================================================================== # 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. # ==================================================================== # # This software consists of voluntary contributions made by many # individuals on behalf of the Apache Software Foundation. For more # information on the Apache Software Foundation, please see # . # Disable logging for unit tests org.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog httpcomponents-client-4.3.3/httpclient/src/test/resources/suffixlist.txt0100644 0000000 0000000 00000002353 12301751660 025514 0ustar000000000 0000000 // ==================================================================== // 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. // ==================================================================== // // This software consists of voluntary contributions made by many // individuals on behalf of the Apache Software Foundation. For more // information on the Apache Software Foundation, please see // . // jp ac.jp *.tokyo.jp !metro.tokyo.jp // unicode no hå.no // invalid xx yy //zzhttpcomponents-client-4.3.3/httpclient-cache/0040755 0000000 0000000 00000000000 12301752765 020043 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/pom.xml0100644 0000000 0000000 00000014067 12301751731 021355 0ustar000000000 0000000 4.0.0 org.apache.httpcomponents httpcomponents-client 4.3.3 httpclient-cache Apache HttpClient Cache 2010 HttpComponents HttpClient - Cache http://hc.apache.org/httpcomponents-client jar org.apache.httpcomponents httpclient ${project.version} compile commons-logging commons-logging compile net.sf.ehcache ehcache-core compile true org.slf4j slf4j-jcl compile true spy spymemcached compile true junit junit test org.easymock easymock test org.easymock easymockclassextension test org.apache.httpcomponents httpclient ${project.version} test-jar test src/main/resources true **/*.properties org.codehaus.mojo build-helper-maven-plugin 1.8 add-source generate-sources add-source src/main/java-deprecated org.apache.maven.plugins maven-jar-plugin test-jar maven-javadoc-plugin ${hc.javadoc.version} true ${maven.compiler.source} http://download.oracle.com/javase/1.5.0/docs/api/ http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/ http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/ javadoc maven-project-info-reports-plugin ${hc.project-info.version} false dependencies dependency-info summary maven-jxr-plugin ${hc.jxr.version} maven-surefire-report-plugin ${hc.surefire-report.version} httpcomponents-client-4.3.3/httpclient-cache/src/0040755 0000000 0000000 00000000000 12301751716 020625 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/0040755 0000000 0000000 00000000000 12301751716 021551 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/0040755 0000000 0000000 00000000000 12301751716 022472 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/0040755 0000000 0000000 00000000000 12301751716 023261 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/0040755 0000000 0000000 00000000000 12301751716 024502 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/0040755 0000000 0000000 00000000000 12301751717 025462 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/0040755 0000000 0000000 00000000000 12301751716 026737 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/0040755 0000000 0000000 00000000000 12301751717 030003 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000161 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/CacheResponseStatus.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/CacheRespons0100644 0000000 0000000 00000004052 12301751717 032301 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.cache; /** * This enumeration represents the various ways a response can be generated * by the {@link org.apache.http.impl.client.cache.CachingHttpClient}; * if a request is executed with an {@link org.apache.http.protocol.HttpContext} * then a parameter with one of these values will be registered in the * context under the key * {@link org.apache.http.impl.client.cache.CachingHttpClient#CACHE_RESPONSE_STATUS}. */ public enum CacheResponseStatus { /** The response was generated directly by the caching module. */ CACHE_MODULE_RESPONSE, /** A response was generated from the cache with no requests sent * upstream. */ CACHE_HIT, /** The response came from an upstream server. */ CACHE_MISS, /** The response was generated from the cache after validating the * entry with the origin server. */ VALIDATED; } ././@LongLink0100644 0000000 0000000 00000000155 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HeaderConstants.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HeaderConsta0100644 0000000 0000000 00000007160 12301751717 032267 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.cache; import org.apache.http.annotation.Immutable; /** * Records static constants for various HTTP header names. * @since 4.1 */ @Immutable public class HeaderConstants { public static final String GET_METHOD = "GET"; public static final String HEAD_METHOD = "HEAD"; public static final String OPTIONS_METHOD = "OPTIONS"; public static final String PUT_METHOD = "PUT"; public static final String DELETE_METHOD = "DELETE"; public static final String TRACE_METHOD = "TRACE"; public static final String LAST_MODIFIED = "Last-Modified"; public static final String IF_MATCH = "If-Match"; public static final String IF_RANGE = "If-Range"; public static final String IF_UNMODIFIED_SINCE = "If-Unmodified-Since"; public static final String IF_MODIFIED_SINCE = "If-Modified-Since"; public static final String IF_NONE_MATCH = "If-None-Match"; public static final String PRAGMA = "Pragma"; public static final String MAX_FORWARDS = "Max-Forwards"; public static final String ETAG = "ETag"; public static final String EXPIRES = "Expires"; public static final String AGE = "Age"; public static final String VARY = "Vary"; public static final String ALLOW = "Allow"; public static final String VIA = "Via"; public static final String PUBLIC = "public"; public static final String PRIVATE = "private"; public static final String CACHE_CONTROL = "Cache-Control"; public static final String CACHE_CONTROL_NO_STORE = "no-store"; public static final String CACHE_CONTROL_NO_CACHE = "no-cache"; public static final String CACHE_CONTROL_MAX_AGE = "max-age"; public static final String CACHE_CONTROL_MAX_STALE = "max-stale"; public static final String CACHE_CONTROL_MIN_FRESH = "min-fresh"; public static final String CACHE_CONTROL_MUST_REVALIDATE = "must-revalidate"; public static final String CACHE_CONTROL_PROXY_REVALIDATE = "proxy-revalidate"; public static final String STALE_IF_ERROR = "stale-if-error"; public static final String STALE_WHILE_REVALIDATE = "stale-while-revalidate"; public static final String WARNING = "Warning"; public static final String RANGE = "Range"; public static final String CONTENT_RANGE = "Content-Range"; public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; public static final String PROXY_AUTHENTICATE = "Proxy-Authenticate"; public static final String AUTHORIZATION = "Authorization"; } ././@LongLink0100644 0000000 0000000 00000000156 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheContext.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheCon0100644 0000000 0000000 00000004702 12301751717 032231 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.cache; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; /** * @since 4.3 */ @NotThreadSafe public class HttpCacheContext extends HttpClientContext { /** * This is the name under which the {@link CacheResponseStatus} of a request * (for example, whether it resulted in a cache hit) will be recorded if an * {@link HttpContext} is provided during execution. */ public static final String CACHE_RESPONSE_STATUS = "http.cache.response.status"; public static HttpCacheContext adapt(final HttpContext context) { if (context instanceof HttpCacheContext) { return (HttpCacheContext) context; } else { return new HttpCacheContext(context); } } public static HttpCacheContext create() { return new HttpCacheContext(new BasicHttpContext()); } public HttpCacheContext(final HttpContext context) { super(context); } public HttpCacheContext() { super(); } public CacheResponseStatus getCacheResponseStatus() { return getAttribute(CACHE_RESPONSE_STATUS, CacheResponseStatus.class); } } ././@LongLink0100644 0000000 0000000 00000000154 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEnt0100644 0000000 0000000 00000021413 12301751717 032236 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.cache; import java.io.Serializable; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.http.Header; import org.apache.http.ProtocolVersion; import org.apache.http.StatusLine; import org.apache.http.annotation.Immutable; import org.apache.http.client.utils.DateUtils; import org.apache.http.message.HeaderGroup; import org.apache.http.protocol.HTTP; import org.apache.http.util.Args; /** * Structure used to store an {@link org.apache.http.HttpResponse} in a cache. * Some entries can optionally depend on system resources that may require * explicit deallocation. In such a case {@link #getResource()} should return * a non null instance of {@link Resource} that must be deallocated by calling * {@link Resource#dispose()} method when no longer used. * * @since 4.1 */ @Immutable public class HttpCacheEntry implements Serializable { private static final long serialVersionUID = -6300496422359477413L; private final Date requestDate; private final Date responseDate; private final StatusLine statusLine; private final HeaderGroup responseHeaders; private final Resource resource; private final Map variantMap; private final Date date; /** * Create a new {@link HttpCacheEntry} with variants. * @param requestDate * Date/time when the request was made (Used for age * calculations) * @param responseDate * Date/time that the response came back (Used for age * calculations) * @param statusLine * HTTP status line from origin response * @param responseHeaders * Header[] from original HTTP Response * @param resource representing origin response body * @param variantMap describing cache entries that are variants * of this parent entry; this maps a "variant key" (derived * from the varying request headers) to a "cache key" (where * in the cache storage the particular variant is located) */ public HttpCacheEntry( final Date requestDate, final Date responseDate, final StatusLine statusLine, final Header[] responseHeaders, final Resource resource, final Map variantMap) { super(); Args.notNull(requestDate, "Request date"); Args.notNull(responseDate, "Response date"); Args.notNull(statusLine, "Status line"); Args.notNull(responseHeaders, "Response headers"); this.requestDate = requestDate; this.responseDate = responseDate; this.statusLine = statusLine; this.responseHeaders = new HeaderGroup(); this.responseHeaders.setHeaders(responseHeaders); this.resource = resource; this.variantMap = variantMap != null ? new HashMap(variantMap) : null; this.date = parseDate(); } /** * Create a new {@link HttpCacheEntry}. * * @param requestDate * Date/time when the request was made (Used for age * calculations) * @param responseDate * Date/time that the response came back (Used for age * calculations) * @param statusLine * HTTP status line from origin response * @param responseHeaders * Header[] from original HTTP Response * @param resource representing origin response body */ public HttpCacheEntry(final Date requestDate, final Date responseDate, final StatusLine statusLine, final Header[] responseHeaders, final Resource resource) { this(requestDate, responseDate, statusLine, responseHeaders, resource, new HashMap()); } /** * Find the "Date" response header and parse it into a java.util.Date * @return the Date value of the header or null if the header is not present */ private Date parseDate() { final Header dateHdr = getFirstHeader(HTTP.DATE_HEADER); if (dateHdr == null) { return null; } return DateUtils.parseDate(dateHdr.getValue()); } /** * Returns the {@link StatusLine} from the origin * {@link org.apache.http.HttpResponse}. */ public StatusLine getStatusLine() { return this.statusLine; } /** * Returns the {@link ProtocolVersion} from the origin * {@link org.apache.http.HttpResponse}. */ public ProtocolVersion getProtocolVersion() { return this.statusLine.getProtocolVersion(); } /** * Gets the reason phrase from the origin * {@link org.apache.http.HttpResponse}, for example, "Not Modified". */ public String getReasonPhrase() { return this.statusLine.getReasonPhrase(); } /** * Returns the HTTP response code from the origin * {@link org.apache.http.HttpResponse}. */ public int getStatusCode() { return this.statusLine.getStatusCode(); } /** * Returns the time the associated origin request was initiated by the * caching module. * @return {@link Date} */ public Date getRequestDate() { return requestDate; } /** * Returns the time the origin response was received by the caching module. * @return {@link Date} */ public Date getResponseDate() { return responseDate; } /** * Returns all the headers that were on the origin response. */ public Header[] getAllHeaders() { return responseHeaders.getAllHeaders(); } /** * Returns the first header from the origin response with the given * name. */ public Header getFirstHeader(final String name) { return responseHeaders.getFirstHeader(name); } /** * Gets all the headers with the given name that were on the origin * response. */ public Header[] getHeaders(final String name) { return responseHeaders.getHeaders(name); } /** * Gets the Date value of the "Date" header or null if the header is missing or cannot be * parsed. * * @since 4.3 */ public Date getDate() { return date; } /** * Returns the {@link Resource} containing the origin response body. */ public Resource getResource() { return this.resource; } /** * Indicates whether the origin response indicated the associated * resource had variants (i.e. that the Vary header was set on the * origin response). * @return {@code true} if this cached response was a variant */ public boolean hasVariants() { return getFirstHeader(HeaderConstants.VARY) != null; } /** * Returns an index about where in the cache different variants for * a given resource are stored. This maps "variant keys" to "cache keys", * where the variant key is derived from the varying request headers, * and the cache key is the location in the * {@link org.apache.http.client.cache.HttpCacheStorage} where that * particular variant is stored. The first variant returned is used as * the "parent" entry to hold this index of the other variants. */ public Map getVariantMap() { return Collections.unmodifiableMap(variantMap); } /** * Provides a string representation of this instance suitable for * human consumption. */ @Override public String toString() { return "[request date=" + this.requestDate + "; response date=" + this.responseDate + "; statusLine=" + this.statusLine + "]"; } } ././@LongLink0100644 0000000 0000000 00000000202 12302131606 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntrySerializationException.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEnt0100644 0000000 0000000 00000003314 12301751717 032236 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.cache; import java.io.IOException; /** * Thrown if serialization or deserialization of an {@link HttpCacheEntry} * fails. */ public class HttpCacheEntrySerializationException extends IOException { private static final long serialVersionUID = 9219188365878433519L; public HttpCacheEntrySerializationException(final String message) { super(); } public HttpCacheEntrySerializationException(final String message, final Throwable cause) { super(message); initCause(cause); } } ././@LongLink0100644 0000000 0000000 00000000166 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntrySerializer.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEnt0100644 0000000 0000000 00000003644 12301751717 032244 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.cache; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * Used by some {@link HttpCacheStorage} implementations to serialize * {@link HttpCacheEntry} instances to a byte representation before * storage. */ public interface HttpCacheEntrySerializer { /** * Serializes the given entry to a byte representation on the * given {@link OutputStream}. * @throws IOException */ void writeTo(HttpCacheEntry entry, OutputStream os) throws IOException; /** * Deserializes a byte representation of a cache entry by reading * from the given {@link InputStream}. * @throws IOException */ HttpCacheEntry readFrom(InputStream is) throws IOException; } ././@LongLink0100644 0000000 0000000 00000000162 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheInvalidator.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheInv0100644 0000000 0000000 00000004030 12301751717 032240 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.cache; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; /** * Given a particular HttpRequest, flush any cache entries that this request * would invalidate. * * @since 4.3 */ public interface HttpCacheInvalidator { /** * Remove cache entries from the cache that are no longer fresh or have been * invalidated in some way. * * @param host * The backend host we are talking to * @param req * The HttpRequest to that host */ void flushInvalidatedCacheEntries(HttpHost host, HttpRequest req); /** * Flushes entries that were invalidated by the given response received for * the given host/request pair. */ void flushInvalidatedCacheEntries(HttpHost host, HttpRequest request, HttpResponse response); } ././@LongLink0100644 0000000 0000000 00000000156 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheStorage.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheSto0100644 0000000 0000000 00000005563 12301751717 032265 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.cache; import java.io.IOException; /** * New storage backends should implement this {@link HttpCacheStorage} * interface. They can then be plugged into the existing * {@link org.apache.http.impl.client.cache.CachingHttpClient} * implementation. * * @since 4.1 */ public interface HttpCacheStorage { /** * Store a given cache entry under the given key. * @param key where in the cache to store the entry * @param entry cached response to store * @throws IOException */ void putEntry(String key, HttpCacheEntry entry) throws IOException; /** * Retrieves the cache entry stored under the given key * or null if no entry exists under that key. * @param key cache key * @return an {@link HttpCacheEntry} or {@code null} if no * entry exists * @throws IOException */ HttpCacheEntry getEntry(String key) throws IOException; /** * Deletes/invalidates/removes any cache entries currently * stored under the given key. * @param key * @throws IOException */ void removeEntry(String key) throws IOException; /** * Atomically applies the given callback to update an existing cache * entry under a given key. * @param key indicates which entry to modify * @param callback performs the update; see * {@link HttpCacheUpdateCallback} for details, but roughly the * callback expects to be handed the current entry and will return * the new value for the entry. * @throws IOException * @throws HttpCacheUpdateException */ void updateEntry( String key, HttpCacheUpdateCallback callback) throws IOException, HttpCacheUpdateException; } ././@LongLink0100644 0000000 0000000 00000000165 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheUpdateCallback.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheUpd0100644 0000000 0000000 00000003743 12301751717 032246 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.cache; import java.io.IOException; /** * Used for atomically updating entries in a {@link HttpCacheStorage} * implementation. The current entry (if any) is fed into an implementation * of this interface, and the new, possibly updated entry (if any) * should be returned. */ public interface HttpCacheUpdateCallback { /** * Returns the new cache entry that should replace an existing one. * * @param existing * the cache entry currently in-place in the cache, possibly * null if nonexistent * @return the cache entry that should replace it, again, * possibly null if the entry should be deleted * * @since 4.1 */ HttpCacheEntry update(HttpCacheEntry existing) throws IOException; } ././@LongLink0100644 0000000 0000000 00000000166 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheUpdateException.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheUpd0100644 0000000 0000000 00000003254 12301751717 032243 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.cache; /** * Signals that {@link HttpCacheStorage} encountered an error performing an * update operation. * * @since 4.1 */ public class HttpCacheUpdateException extends Exception { private static final long serialVersionUID = 823573584868632876L; public HttpCacheUpdateException(final String message) { super(message); } public HttpCacheUpdateException(final String message, final Throwable cause) { super(message); initCause(cause); } } ././@LongLink0100644 0000000 0000000 00000000150 12302131606 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/InputLimit.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/InputLimit.j0100644 0000000 0000000 00000004315 12301751717 032254 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.cache; import org.apache.http.annotation.NotThreadSafe; /** * Used to limiting the size of an incoming response body of * unknown size that is optimistically being read in anticipation * of caching it. * @since 4.1 */ @NotThreadSafe // reached public class InputLimit { private final long value; private boolean reached; /** * Create a limit for how many bytes of a response body to * read. * @param value maximum length in bytes */ public InputLimit(final long value) { super(); this.value = value; this.reached = false; } /** * Returns the current maximum limit that was set on * creation. */ public long getValue() { return this.value; } /** * Used to report that the limit has been reached. */ public void reached() { this.reached = true; } /** * Returns {@code true} if the input limit has been reached. */ public boolean isReached() { return this.reached; } } ././@LongLink0100644 0000000 0000000 00000000145 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/package.htmlhttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/package.html0100644 0000000 0000000 00000007160 12301751717 032265 0ustar000000000 0000000

This package consists largely of constants and interfaces that are necessary for building new storage backends for the {@link org.apache.http.impl.client.cache.CachingHttpClient} or for those clients wanting to get a little more behavioral information out of the cache module (for example, whether a particular response was a cache hit or not). Developers that simply want to instantiate and make use of the caching module will be better off looking at the {@code CachingHttpClient} documentation itself.

The classes in this package can be divided into two main groups: reference constants and interfaces needed for storage backends. In the former group, {@link org.apache.http.client.cache.HeaderConstants} contains a list of HTTP header names encoded as static fields, and the {@link org.apache.http.client.cache.CacheResponseStatus} enumeration values are set in an {@link org.apache.http.protocol.HttpContext} by the {@code CachingHttpClient} to indicate how the request was processed by the caching module itself.

New storage backends will need to implement the {@link org.apache.http.client.cache.HttpCacheStorage} interface; they can then be passed to one of the {@code CachingHttpClient} constructors, which will happily make use of the new storage mechanism. The {@link org.apache.http.client.cache.HttpCacheEntry} class shows the datastructure for a cache entry that must be stored by the {@code HttpCacheStorage}. There is, in addition, the notion of a {@link org.apache.http.client.cache.Resource} and an associated {@link org.apache.http.client.cache.ResourceFactory}, which are used for managing the handling of cached response bodies. The default implementation used by the {@code CachingHttpClient} stores response bodies in memory; alternative implementations might involve storing these in a filesystem. A new {@code ResourceFactory} can be provided along with a {@code HttpCacheStorage} in one of the constructors to the {@code CachingHttpClient}. Finally, some of the additional storage backends we provide, like the {@link org.apache.http.impl.client.cache.ehcache.EhcacheHttpCacheStorage} and {@link org.apache.http.impl.client.cache.memcached.MemcachedHttpCacheStorage}, can be provided with different serializers for the cache entry metadata; developers wanting to experiment with different serialization techniques should implement the {@link org.apache.http.client.cache.HttpCacheEntrySerializer} interface.

././@LongLink0100644 0000000 0000000 00000000146 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/Resource.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/Resource.jav0100644 0000000 0000000 00000003617 12301751717 032300 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.cache; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; /** * Represents a disposable system resource used for handling * cached response bodies. * * @since 4.1 */ public interface Resource extends Serializable { /** * Returns an {@link InputStream} from which the response * body can be read. * @throws IOException */ InputStream getInputStream() throws IOException; /** * Returns the length in bytes of the response body. */ long length(); /** * Indicates the system no longer needs to keep this * response body and any system resources associated with * it may be reclaimed. */ void dispose(); } ././@LongLink0100644 0000000 0000000 00000000155 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/ResourceFactory.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/client/cache/ResourceFact0100644 0000000 0000000 00000005066 12301751717 032317 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.cache; import java.io.IOException; import java.io.InputStream; /** * Generates {@link Resource} instances for handling cached * HTTP response bodies. * * @since 4.1 */ public interface ResourceFactory { /** * Creates a {@link Resource} from a given response body. * @param requestId a unique identifier for this particular * response body * @param instream the original {@link InputStream} * containing the response body of the origin HTTP response. * @param limit maximum number of bytes to consume of the * response body; if this limit is reached before the * response body is fully consumed, mark the limit has * having been reached and return a {@code Resource} * containing the data read to that point. * @return a {@code Resource} containing however much of * the response body was successfully read. * @throws IOException */ Resource generate(String requestId, InputStream instream, InputLimit limit) throws IOException; /** * Clones an existing {@link Resource}. * @param requestId unique identifier provided to associate * with the cloned response body. * @param resource the original response body to clone. * @return the {@code Resource} copy * @throws IOException */ Resource copy(String requestId, Resource resource) throws IOException; } httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/0040755 0000000 0000000 00000000000 12301751717 026423 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/0040755 0000000 0000000 00000000000 12301751717 027701 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/0040755 0000000 0000000 00000000000 12301751725 030743 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000200 12302131606 011615 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/AsynchronousValidationRequest.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Asynchr0100644 0000000 0000000 00000014642 12301751724 032300 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpException; import org.apache.http.HttpResponse; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; /** * Class used to represent an asynchronous revalidation event, such as with * "stale-while-revalidate" */ class AsynchronousValidationRequest implements Runnable { private final AsynchronousValidator parent; private final CachingExec cachingExec; private final HttpRoute route; private final HttpRequestWrapper request; private final HttpClientContext context; private final HttpExecutionAware execAware; private final HttpCacheEntry cacheEntry; private final String identifier; private final int consecutiveFailedAttempts; private final Log log = LogFactory.getLog(getClass()); /** * Used internally by {@link AsynchronousValidator} to schedule a * revalidation. * @param request * @param context * @param cacheEntry * @param identifier * @param consecutiveFailedAttempts */ AsynchronousValidationRequest( final AsynchronousValidator parent, final CachingExec cachingExec, final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware, final HttpCacheEntry cacheEntry, final String identifier, final int consecutiveFailedAttempts) { this.parent = parent; this.cachingExec = cachingExec; this.route = route; this.request = request; this.context = context; this.execAware = execAware; this.cacheEntry = cacheEntry; this.identifier = identifier; this.consecutiveFailedAttempts = consecutiveFailedAttempts; } public void run() { try { if (revalidateCacheEntry()) { parent.jobSuccessful(identifier); } else { parent.jobFailed(identifier); } } finally { parent.markComplete(identifier); } } /** * Revalidate the cache entry and return if the operation was successful. * Success means a connection to the server was established and replay did * not indicate a server error. * @return true if the cache entry was successfully validated; * otherwise false */ protected boolean revalidateCacheEntry() { try { final CloseableHttpResponse httpResponse = cachingExec.revalidateCacheEntry(route, request, context, execAware, cacheEntry); try { final int statusCode = httpResponse.getStatusLine().getStatusCode(); return isNotServerError(statusCode) && isNotStale(httpResponse); } finally { httpResponse.close(); } } catch (final IOException ioe) { log.debug("Asynchronous revalidation failed due to I/O error", ioe); return false; } catch (final HttpException pe) { log.error("HTTP protocol exception during asynchronous revalidation", pe); return false; } catch (final RuntimeException re) { log.error("RuntimeException thrown during asynchronous revalidation: " + re); return false; } } /** * Return whether the status code indicates a server error or not. * @param statusCode the status code to be checked * @return if the status code indicates a server error or not */ private boolean isNotServerError(final int statusCode) { return statusCode < 500; } /** * Try to detect if the returned response is generated from a stale cache entry. * @param httpResponse the response to be checked * @return whether the response is stale or not */ private boolean isNotStale(final HttpResponse httpResponse) { final Header[] warnings = httpResponse.getHeaders(HeaderConstants.WARNING); if (warnings != null) { for (final Header warning : warnings) { /** * warn-codes * 110 = Response is stale * 111 = Revalidation failed */ final String warningValue = warning.getValue(); if (warningValue.startsWith("110") || warningValue.startsWith("111")) { return false; } } } return true; } String getIdentifier() { return identifier; } /** * The number of consecutively failed revalidation attempts. * @return the number of consecutively failed revalidation attempts. */ public int getConsecutiveFailedAttempts() { return consecutiveFailedAttempts; } } ././@LongLink0100644 0000000 0000000 00000000170 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/AsynchronousValidator.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Asynchr0100644 0000000 0000000 00000013673 12301751724 032303 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.Closeable; import java.io.IOException; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.concurrent.RejectedExecutionException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; /** * Class used for asynchronous revalidations to be used when the "stale- * while-revalidate" directive is present */ class AsynchronousValidator implements Closeable { private final SchedulingStrategy schedulingStrategy; private final Set queued; private final CacheKeyGenerator cacheKeyGenerator; private final FailureCache failureCache; private final Log log = LogFactory.getLog(getClass()); /** * Create AsynchronousValidator which will make revalidation requests * using an {@link ImmediateSchedulingStrategy}. Its thread * pool will be configured according to the given {@link CacheConfig}. * @param config specifies thread pool settings. See * {@link CacheConfig#getAsynchronousWorkersMax()}, * {@link CacheConfig#getAsynchronousWorkersCore()}, * {@link CacheConfig#getAsynchronousWorkerIdleLifetimeSecs()}, * and {@link CacheConfig#getRevalidationQueueSize()}. */ public AsynchronousValidator(final CacheConfig config) { this(new ImmediateSchedulingStrategy(config)); } /** * Create AsynchronousValidator which will make revalidation requests * using the supplied {@link SchedulingStrategy}. Closing the validator * will also close the given schedulingStrategy. * @param schedulingStrategy used to maintain a pool of worker threads and * schedules when requests are executed */ AsynchronousValidator(final SchedulingStrategy schedulingStrategy) { this.schedulingStrategy = schedulingStrategy; this.queued = new HashSet(); this.cacheKeyGenerator = new CacheKeyGenerator(); this.failureCache = new DefaultFailureCache(); } public void close() throws IOException { schedulingStrategy.close(); } /** * Schedules an asynchronous revalidation */ public synchronized void revalidateCacheEntry( final CachingExec cachingExec, final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware, final HttpCacheEntry entry) { // getVariantURI will fall back on getURI if no variants exist final String uri = cacheKeyGenerator.getVariantURI(context.getTargetHost(), request, entry); if (!queued.contains(uri)) { final int consecutiveFailedAttempts = failureCache.getErrorCount(uri); final AsynchronousValidationRequest revalidationRequest = new AsynchronousValidationRequest( this, cachingExec, route, request, context, execAware, entry, uri, consecutiveFailedAttempts); try { schedulingStrategy.schedule(revalidationRequest); queued.add(uri); } catch (final RejectedExecutionException ree) { log.debug("Revalidation for [" + uri + "] not scheduled: " + ree); } } } /** * Removes an identifier from the internal list of revalidation jobs in * progress. This is meant to be called by * {@link AsynchronousValidationRequest#run()} once the revalidation is * complete, using the identifier passed in during constructions. * @param identifier */ synchronized void markComplete(final String identifier) { queued.remove(identifier); } /** * The revalidation job was successful thus the number of consecutive * failed attempts will be reset to zero. Should be called by * {@link AsynchronousValidationRequest#run()}. * @param identifier the revalidation job's unique identifier */ void jobSuccessful(final String identifier) { failureCache.resetErrorCount(identifier); } /** * The revalidation job did fail and thus the number of consecutive failed * attempts will be increased. Should be called by * {@link AsynchronousValidationRequest#run()}. * @param identifier the revalidation job's unique identifier */ void jobFailed(final String identifier) { failureCache.increaseErrorCount(identifier); } Set getScheduledIdentifiers() { return Collections.unmodifiableSet(queued); } } ././@LongLink0100644 0000000 0000000 00000000161 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/BasicHttpCache.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/BasicHt0100644 0000000 0000000 00000036150 12301751724 032204 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheInvalidator; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.client.cache.HttpCacheUpdateCallback; import org.apache.http.client.cache.HttpCacheUpdateException; import org.apache.http.client.cache.Resource; import org.apache.http.client.cache.ResourceFactory; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.message.BasicHttpResponse; import org.apache.http.protocol.HTTP; class BasicHttpCache implements HttpCache { private static final Set safeRequestMethods = new HashSet( Arrays.asList(HeaderConstants.HEAD_METHOD, HeaderConstants.GET_METHOD, HeaderConstants.OPTIONS_METHOD, HeaderConstants.TRACE_METHOD)); private final CacheKeyGenerator uriExtractor; private final ResourceFactory resourceFactory; private final long maxObjectSizeBytes; private final CacheEntryUpdater cacheEntryUpdater; private final CachedHttpResponseGenerator responseGenerator; private final HttpCacheInvalidator cacheInvalidator; private final HttpCacheStorage storage; private final Log log = LogFactory.getLog(getClass()); public BasicHttpCache( final ResourceFactory resourceFactory, final HttpCacheStorage storage, final CacheConfig config, final CacheKeyGenerator uriExtractor, final HttpCacheInvalidator cacheInvalidator) { this.resourceFactory = resourceFactory; this.uriExtractor = uriExtractor; this.cacheEntryUpdater = new CacheEntryUpdater(resourceFactory); this.maxObjectSizeBytes = config.getMaxObjectSize(); this.responseGenerator = new CachedHttpResponseGenerator(); this.storage = storage; this.cacheInvalidator = cacheInvalidator; } public BasicHttpCache( final ResourceFactory resourceFactory, final HttpCacheStorage storage, final CacheConfig config, final CacheKeyGenerator uriExtractor) { this( resourceFactory, storage, config, uriExtractor, new CacheInvalidator(uriExtractor, storage)); } public BasicHttpCache( final ResourceFactory resourceFactory, final HttpCacheStorage storage, final CacheConfig config) { this( resourceFactory, storage, config, new CacheKeyGenerator()); } public BasicHttpCache(final CacheConfig config) { this(new HeapResourceFactory(), new BasicHttpCacheStorage(config), config); } public BasicHttpCache() { this(CacheConfig.DEFAULT); } public void flushCacheEntriesFor(final HttpHost host, final HttpRequest request) throws IOException { if (!safeRequestMethods.contains(request.getRequestLine().getMethod())) { final String uri = uriExtractor.getURI(host, request); storage.removeEntry(uri); } } public void flushInvalidatedCacheEntriesFor(final HttpHost host, final HttpRequest request, final HttpResponse response) { if (!safeRequestMethods.contains(request.getRequestLine().getMethod())) { cacheInvalidator.flushInvalidatedCacheEntries(host, request, response); } } void storeInCache( final HttpHost target, final HttpRequest request, final HttpCacheEntry entry) throws IOException { if (entry.hasVariants()) { storeVariantEntry(target, request, entry); } else { storeNonVariantEntry(target, request, entry); } } void storeNonVariantEntry( final HttpHost target, final HttpRequest req, final HttpCacheEntry entry) throws IOException { final String uri = uriExtractor.getURI(target, req); storage.putEntry(uri, entry); } void storeVariantEntry( final HttpHost target, final HttpRequest req, final HttpCacheEntry entry) throws IOException { final String parentURI = uriExtractor.getURI(target, req); final String variantURI = uriExtractor.getVariantURI(target, req, entry); storage.putEntry(variantURI, entry); final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback() { public HttpCacheEntry update(final HttpCacheEntry existing) throws IOException { return doGetUpdatedParentEntry( req.getRequestLine().getUri(), existing, entry, uriExtractor.getVariantKey(req, entry), variantURI); } }; try { storage.updateEntry(parentURI, callback); } catch (final HttpCacheUpdateException e) { log.warn("Could not update key [" + parentURI + "]", e); } } public void reuseVariantEntryFor(final HttpHost target, final HttpRequest req, final Variant variant) throws IOException { final String parentCacheKey = uriExtractor.getURI(target, req); final HttpCacheEntry entry = variant.getEntry(); final String variantKey = uriExtractor.getVariantKey(req, entry); final String variantCacheKey = variant.getCacheKey(); final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback() { public HttpCacheEntry update(final HttpCacheEntry existing) throws IOException { return doGetUpdatedParentEntry(req.getRequestLine().getUri(), existing, entry, variantKey, variantCacheKey); } }; try { storage.updateEntry(parentCacheKey, callback); } catch (final HttpCacheUpdateException e) { log.warn("Could not update key [" + parentCacheKey + "]", e); } } boolean isIncompleteResponse(final HttpResponse resp, final Resource resource) { final int status = resp.getStatusLine().getStatusCode(); if (status != HttpStatus.SC_OK && status != HttpStatus.SC_PARTIAL_CONTENT) { return false; } final Header hdr = resp.getFirstHeader(HTTP.CONTENT_LEN); if (hdr == null) { return false; } final int contentLength; try { contentLength = Integer.parseInt(hdr.getValue()); } catch (final NumberFormatException nfe) { return false; } return (resource.length() < contentLength); } CloseableHttpResponse generateIncompleteResponseError( final HttpResponse response, final Resource resource) { final int contentLength = Integer.parseInt(response.getFirstHeader(HTTP.CONTENT_LEN).getValue()); final HttpResponse error = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_BAD_GATEWAY, "Bad Gateway"); error.setHeader("Content-Type","text/plain;charset=UTF-8"); final String msg = String.format("Received incomplete response " + "with Content-Length %d but actual body length %d", contentLength, resource.length()); final byte[] msgBytes = msg.getBytes(); error.setHeader("Content-Length", Integer.toString(msgBytes.length)); error.setEntity(new ByteArrayEntity(msgBytes)); return Proxies.enhanceResponse(error); } HttpCacheEntry doGetUpdatedParentEntry( final String requestId, final HttpCacheEntry existing, final HttpCacheEntry entry, final String variantKey, final String variantCacheKey) throws IOException { HttpCacheEntry src = existing; if (src == null) { src = entry; } Resource resource = null; if (src.getResource() != null) { resource = resourceFactory.copy(requestId, src.getResource()); } final Map variantMap = new HashMap(src.getVariantMap()); variantMap.put(variantKey, variantCacheKey); return new HttpCacheEntry( src.getRequestDate(), src.getResponseDate(), src.getStatusLine(), src.getAllHeaders(), resource, variantMap); } public HttpCacheEntry updateCacheEntry(final HttpHost target, final HttpRequest request, final HttpCacheEntry stale, final HttpResponse originResponse, final Date requestSent, final Date responseReceived) throws IOException { final HttpCacheEntry updatedEntry = cacheEntryUpdater.updateCacheEntry( request.getRequestLine().getUri(), stale, requestSent, responseReceived, originResponse); storeInCache(target, request, updatedEntry); return updatedEntry; } public HttpCacheEntry updateVariantCacheEntry(final HttpHost target, final HttpRequest request, final HttpCacheEntry stale, final HttpResponse originResponse, final Date requestSent, final Date responseReceived, final String cacheKey) throws IOException { final HttpCacheEntry updatedEntry = cacheEntryUpdater.updateCacheEntry( request.getRequestLine().getUri(), stale, requestSent, responseReceived, originResponse); storage.putEntry(cacheKey, updatedEntry); return updatedEntry; } public HttpResponse cacheAndReturnResponse(final HttpHost host, final HttpRequest request, final HttpResponse originResponse, final Date requestSent, final Date responseReceived) throws IOException { return cacheAndReturnResponse(host, request, Proxies.enhanceResponse(originResponse), requestSent, responseReceived); } public CloseableHttpResponse cacheAndReturnResponse( final HttpHost host, final HttpRequest request, final CloseableHttpResponse originResponse, final Date requestSent, final Date responseReceived) throws IOException { boolean closeOriginResponse = true; final SizeLimitedResponseReader responseReader = getResponseReader(request, originResponse); try { responseReader.readResponse(); if (responseReader.isLimitReached()) { closeOriginResponse = false; return responseReader.getReconstructedResponse(); } final Resource resource = responseReader.getResource(); if (isIncompleteResponse(originResponse, resource)) { return generateIncompleteResponseError(originResponse, resource); } final HttpCacheEntry entry = new HttpCacheEntry( requestSent, responseReceived, originResponse.getStatusLine(), originResponse.getAllHeaders(), resource); storeInCache(host, request, entry); return responseGenerator.generateResponse(entry); } finally { if (closeOriginResponse) { originResponse.close(); } } } SizeLimitedResponseReader getResponseReader(final HttpRequest request, final CloseableHttpResponse backEndResponse) { return new SizeLimitedResponseReader( resourceFactory, maxObjectSizeBytes, request, backEndResponse); } public HttpCacheEntry getCacheEntry(final HttpHost host, final HttpRequest request) throws IOException { final HttpCacheEntry root = storage.getEntry(uriExtractor.getURI(host, request)); if (root == null) { return null; } if (!root.hasVariants()) { return root; } final String variantCacheKey = root.getVariantMap().get(uriExtractor.getVariantKey(request, root)); if (variantCacheKey == null) { return null; } return storage.getEntry(variantCacheKey); } public void flushInvalidatedCacheEntriesFor(final HttpHost host, final HttpRequest request) throws IOException { cacheInvalidator.flushInvalidatedCacheEntries(host, request); } public Map getVariantCacheEntriesWithEtags(final HttpHost host, final HttpRequest request) throws IOException { final Map variants = new HashMap(); final HttpCacheEntry root = storage.getEntry(uriExtractor.getURI(host, request)); if (root == null || !root.hasVariants()) { return variants; } for(final Map.Entry variant : root.getVariantMap().entrySet()) { final String variantKey = variant.getKey(); final String variantCacheKey = variant.getValue(); addVariantWithEtag(variantKey, variantCacheKey, variants); } return variants; } private void addVariantWithEtag(final String variantKey, final String variantCacheKey, final Map variants) throws IOException { final HttpCacheEntry entry = storage.getEntry(variantCacheKey); if (entry == null) { return; } final Header etagHeader = entry.getFirstHeader(HeaderConstants.ETAG); if (etagHeader == null) { return; } variants.put(etagHeader.getValue(), new Variant(variantKey, variantCacheKey, entry)); } } ././@LongLink0100644 0000000 0000000 00000000170 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/BasicHttpCacheStorage.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/BasicHt0100644 0000000 0000000 00000006471 12301751722 032205 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.client.cache.HttpCacheUpdateCallback; /** * Basic {@link HttpCacheStorage} implementation backed by an instance of * {@link java.util.LinkedHashMap}. In other words, cache entries and * the cached response bodies are held in-memory. This cache does NOT * deallocate resources associated with the cache entries; it is intended * for use with {@link HeapResource} and similar. This is the default cache * storage backend used by {@link CachingHttpClients}. * * @since 4.1 */ @ThreadSafe public class BasicHttpCacheStorage implements HttpCacheStorage { private final CacheMap entries; public BasicHttpCacheStorage(final CacheConfig config) { super(); this.entries = new CacheMap(config.getMaxCacheEntries()); } /** * Places a HttpCacheEntry in the cache * * @param url * Url to use as the cache key * @param entry * HttpCacheEntry to place in the cache */ public synchronized void putEntry(final String url, final HttpCacheEntry entry) throws IOException { entries.put(url, entry); } /** * Gets an entry from the cache, if it exists * * @param url * Url that is the cache key * @return HttpCacheEntry if one exists, or null for cache miss */ public synchronized HttpCacheEntry getEntry(final String url) throws IOException { return entries.get(url); } /** * Removes a HttpCacheEntry from the cache * * @param url * Url that is the cache key */ public synchronized void removeEntry(final String url) throws IOException { entries.remove(url); } public synchronized void updateEntry( final String url, final HttpCacheUpdateCallback callback) throws IOException { final HttpCacheEntry existingEntry = entries.get(url); entries.put(url, callback.update(existingEntry)); } } ././@LongLink0100644 0000000 0000000 00000000163 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/BasicIdGenerator.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/BasicId0100644 0000000 0000000 00000005451 12301751724 032165 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.net.InetAddress; import java.net.UnknownHostException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Formatter; import java.util.Locale; import org.apache.http.annotation.GuardedBy; import org.apache.http.annotation.ThreadSafe; /** * Should produce reasonably unique tokens. */ @ThreadSafe class BasicIdGenerator { private final String hostname; private final SecureRandom rnd; @GuardedBy("this") private long count; public BasicIdGenerator() { super(); String hostname; try { hostname = InetAddress.getLocalHost().getHostName(); } catch (final UnknownHostException ex) { hostname = "localhost"; } this.hostname = hostname; try { this.rnd = SecureRandom.getInstance("SHA1PRNG"); } catch (final NoSuchAlgorithmException ex) { throw new Error(ex); } this.rnd.setSeed(System.currentTimeMillis()); } public synchronized void generate(final StringBuilder buffer) { this.count++; final int rndnum = this.rnd.nextInt(); buffer.append(System.currentTimeMillis()); buffer.append('.'); final Formatter formatter = new Formatter(buffer, Locale.US); formatter.format("%1$016x-%2$08x", this.count, rndnum); formatter.close(); buffer.append('.'); buffer.append(this.hostname); } public String generate() { final StringBuilder buffer = new StringBuilder(); generate(buffer); return buffer.toString(); } } ././@LongLink0100644 0000000 0000000 00000000171 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheableRequestPolicy.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Cacheab0100644 0000000 0000000 00000007114 12301751724 032173 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpRequest; import org.apache.http.HttpVersion; import org.apache.http.ProtocolVersion; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.HeaderConstants; /** * Determines if an HttpRequest is allowed to be served from the cache. * * @since 4.1 */ @Immutable class CacheableRequestPolicy { private final Log log = LogFactory.getLog(getClass()); /** * Determines if an HttpRequest can be served from the cache. * * @param request * an HttpRequest * @return boolean Is it possible to serve this request from cache */ public boolean isServableFromCache(final HttpRequest request) { final String method = request.getRequestLine().getMethod(); final ProtocolVersion pv = request.getRequestLine().getProtocolVersion(); if (HttpVersion.HTTP_1_1.compareToVersion(pv) != 0) { log.trace("non-HTTP/1.1 request was not serveable from cache"); return false; } if (!method.equals(HeaderConstants.GET_METHOD)) { log.trace("non-GET request was not serveable from cache"); return false; } if (request.getHeaders(HeaderConstants.PRAGMA).length > 0) { log.trace("request with Pragma header was not serveable from cache"); return false; } final Header[] cacheControlHeaders = request.getHeaders(HeaderConstants.CACHE_CONTROL); for (final Header cacheControl : cacheControlHeaders) { for (final HeaderElement cacheControlElement : cacheControl.getElements()) { if (HeaderConstants.CACHE_CONTROL_NO_STORE.equalsIgnoreCase(cacheControlElement .getName())) { log.trace("Request with no-store was not serveable from cache"); return false; } if (HeaderConstants.CACHE_CONTROL_NO_CACHE.equalsIgnoreCase(cacheControlElement .getName())) { log.trace("Request with no-cache was not serveable from cache"); return false; } } } log.trace("Request was serveable from cache"); return true; } } ././@LongLink0100644 0000000 0000000 00000000156 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheConfig.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheCo0100644 0000000 0000000 00000075202 12301751722 032153 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.apache.http.util.Args; /** *

Java Beans-style configuration for a {@link CachingHttpClient}. Any class * in the caching module that has configuration options should take a * {@link CacheConfig} argument in one of its constructors. A * {@code CacheConfig} instance has sane and conservative defaults, so the * easiest way to specify options is to get an instance and then set just * the options you want to modify from their defaults.

* *

N.B. This class is only for caching-specific configuration; to * configure the behavior of the rest of the client, configure the * {@link org.apache.http.client.HttpClient} used as the "backend" * for the {@code CachingHttpClient}.

* *

Cache configuration can be grouped into the following categories:

* *

Cache size. If the backend storage supports these limits, you * can specify the {@link CacheConfig#getMaxCacheEntries maximum number of * cache entries} as well as the {@link CacheConfig#getMaxObjectSizeBytes * maximum cacheable response body size}.

* *

Public/private caching. By default, the caching module considers * itself to be a shared (public) cache, and will not, for example, cache * responses to requests with {@code Authorization} headers or responses * marked with {@code Cache-Control: private}. If, however, the cache * is only going to be used by one logical "user" (behaving similarly to a * browser cache), then you will want to {@link * CacheConfig#setSharedCache(boolean) turn off the shared cache setting}.

* *

303 caching. RFC2616 explicitly disallows caching 303 responses; * however, the HTTPbis working group says they can be cached * if explicitly indicated in the response headers and permitted by the request method. * (They also indicate that disallowing 303 caching is actually an unintended * spec error in RFC2616). * This behavior is off by default, to err on the side of a conservative * adherence to the existing standard, but you may want to * {@link Builder#setAllow303Caching(boolean) enable it}. * *

Weak ETags on PUT/DELETE If-Match requests. RFC2616 explicitly * prohibits the use of weak validators in non-GET requests, however, the * HTTPbis working group says while the limitation for weak validators on ranged * requests makes sense, weak ETag validation is useful on full non-GET * requests; e.g., PUT with If-Match. This behavior is off by default, to err on * the side of a conservative adherence to the existing standard, but you may * want to {@link Builder#setWeakETagOnPutDeleteAllowed(boolean) enable it}. * *

Heuristic caching. Per RFC2616, a cache may cache certain cache * entries even if no explicit cache control headers are set by the origin. * This behavior is off by default, but you may want to turn this on if you * are working with an origin that doesn't set proper headers but where you * still want to cache the responses. You will want to {@link * CacheConfig#setHeuristicCachingEnabled(boolean) enable heuristic caching}, * then specify either a {@link CacheConfig#getHeuristicDefaultLifetime() * default freshness lifetime} and/or a {@link * CacheConfig#setHeuristicCoefficient(float) fraction of the time since * the resource was last modified}. See Sections * * 13.2.2 and * 13.2.4 of the HTTP/1.1 RFC for more details on heuristic caching.

* *

Background validation. The cache module supports the * {@code stale-while-revalidate} directive of * RFC5861, which allows * certain cache entry revalidations to happen in the background. You may * want to tweak the settings for the {@link * CacheConfig#getAsynchronousWorkersCore() minimum} and {@link * CacheConfig#getAsynchronousWorkersMax() maximum} number of background * worker threads, as well as the {@link * CacheConfig#getAsynchronousWorkerIdleLifetimeSecs() maximum time they * can be idle before being reclaimed}. You can also control the {@link * CacheConfig#getRevalidationQueueSize() size of the queue} used for * revalidations when there aren't enough workers to keep up with demand. */ public class CacheConfig implements Cloneable { /** Default setting for the maximum object size that will be * cached, in bytes. */ public final static int DEFAULT_MAX_OBJECT_SIZE_BYTES = 8192; /** Default setting for the maximum number of cache entries * that will be retained. */ public final static int DEFAULT_MAX_CACHE_ENTRIES = 1000; /** Default setting for the number of retries on a failed * cache update */ public final static int DEFAULT_MAX_UPDATE_RETRIES = 1; /** Default setting for 303 caching */ public final static boolean DEFAULT_303_CACHING_ENABLED = false; /** Default setting to allow weak tags on PUT/DELETE methods */ public final static boolean DEFAULT_WEAK_ETAG_ON_PUTDELETE_ALLOWED = false; /** Default setting for heuristic caching */ public final static boolean DEFAULT_HEURISTIC_CACHING_ENABLED = false; /** Default coefficient used to heuristically determine freshness * lifetime from the Last-Modified time of a cache entry. */ public final static float DEFAULT_HEURISTIC_COEFFICIENT = 0.1f; /** Default lifetime in seconds to be assumed when we cannot calculate * freshness heuristically. */ public final static long DEFAULT_HEURISTIC_LIFETIME = 0; /** Default number of worker threads to allow for background revalidations * resulting from the stale-while-revalidate directive. */ public static final int DEFAULT_ASYNCHRONOUS_WORKERS_MAX = 1; /** Default minimum number of worker threads to allow for background * revalidations resulting from the stale-while-revalidate directive. */ public static final int DEFAULT_ASYNCHRONOUS_WORKERS_CORE = 1; /** Default maximum idle lifetime for a background revalidation thread * before it gets reclaimed. */ public static final int DEFAULT_ASYNCHRONOUS_WORKER_IDLE_LIFETIME_SECS = 60; /** Default maximum queue length for background revalidation requests. */ public static final int DEFAULT_REVALIDATION_QUEUE_SIZE = 100; public static final CacheConfig DEFAULT = new Builder().build(); // TODO: make final private long maxObjectSize; private int maxCacheEntries; private int maxUpdateRetries; private boolean allow303Caching; private boolean weakETagOnPutDeleteAllowed; private boolean heuristicCachingEnabled; private float heuristicCoefficient; private long heuristicDefaultLifetime; private boolean isSharedCache; private int asynchronousWorkersMax; private int asynchronousWorkersCore; private int asynchronousWorkerIdleLifetimeSecs; private int revalidationQueueSize; private boolean neverCacheHTTP10ResponsesWithQuery; /** * @deprecated (4.3) use {@link Builder}. */ @Deprecated public CacheConfig() { super(); this.maxObjectSize = DEFAULT_MAX_OBJECT_SIZE_BYTES; this.maxCacheEntries = DEFAULT_MAX_CACHE_ENTRIES; this.maxUpdateRetries = DEFAULT_MAX_UPDATE_RETRIES; this.allow303Caching = DEFAULT_303_CACHING_ENABLED; this.weakETagOnPutDeleteAllowed = DEFAULT_WEAK_ETAG_ON_PUTDELETE_ALLOWED; this.heuristicCachingEnabled = DEFAULT_HEURISTIC_CACHING_ENABLED; this.heuristicCoefficient = DEFAULT_HEURISTIC_COEFFICIENT; this.heuristicDefaultLifetime = DEFAULT_HEURISTIC_LIFETIME; this.isSharedCache = true; this.asynchronousWorkersMax = DEFAULT_ASYNCHRONOUS_WORKERS_MAX; this.asynchronousWorkersCore = DEFAULT_ASYNCHRONOUS_WORKERS_CORE; this.asynchronousWorkerIdleLifetimeSecs = DEFAULT_ASYNCHRONOUS_WORKER_IDLE_LIFETIME_SECS; this.revalidationQueueSize = DEFAULT_REVALIDATION_QUEUE_SIZE; } CacheConfig( final long maxObjectSize, final int maxCacheEntries, final int maxUpdateRetries, final boolean allow303Caching, final boolean weakETagOnPutDeleteAllowed, final boolean heuristicCachingEnabled, final float heuristicCoefficient, final long heuristicDefaultLifetime, final boolean isSharedCache, final int asynchronousWorkersMax, final int asynchronousWorkersCore, final int asynchronousWorkerIdleLifetimeSecs, final int revalidationQueueSize, final boolean neverCacheHTTP10ResponsesWithQuery) { super(); this.maxObjectSize = maxObjectSize; this.maxCacheEntries = maxCacheEntries; this.maxUpdateRetries = maxUpdateRetries; this.allow303Caching = allow303Caching; this.weakETagOnPutDeleteAllowed = weakETagOnPutDeleteAllowed; this.heuristicCachingEnabled = heuristicCachingEnabled; this.heuristicCoefficient = heuristicCoefficient; this.heuristicDefaultLifetime = heuristicDefaultLifetime; this.isSharedCache = isSharedCache; this.asynchronousWorkersMax = asynchronousWorkersMax; this.asynchronousWorkersCore = asynchronousWorkersCore; this.asynchronousWorkerIdleLifetimeSecs = asynchronousWorkerIdleLifetimeSecs; this.revalidationQueueSize = revalidationQueueSize; } /** * Returns the current maximum response body size that will be cached. * @return size in bytes * * @deprecated (4.2) use {@link #getMaxObjectSize()} */ @Deprecated public int getMaxObjectSizeBytes() { return maxObjectSize > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) maxObjectSize; } /** * Specifies the maximum response body size that will be eligible for caching. * @param maxObjectSizeBytes size in bytes * * @deprecated (4.2) use {@link Builder}. */ @Deprecated public void setMaxObjectSizeBytes(final int maxObjectSizeBytes) { if (maxObjectSizeBytes > Integer.MAX_VALUE) { this.maxObjectSize = Integer.MAX_VALUE; } else { this.maxObjectSize = maxObjectSizeBytes; } } /** * Returns the current maximum response body size that will be cached. * @return size in bytes * * @since 4.2 */ public long getMaxObjectSize() { return maxObjectSize; } /** * Specifies the maximum response body size that will be eligible for caching. * @param maxObjectSize size in bytes * * @since 4.2 * * @deprecated (4.3) use {@link Builder}. */ @Deprecated public void setMaxObjectSize(final long maxObjectSize) { this.maxObjectSize = maxObjectSize; } /** * Returns whether the cache will never cache HTTP 1.0 responses with a query string or not. * @return {@code true} to not cache query string responses, {@code false} to cache if explicit cache headers are * found */ public boolean isNeverCacheHTTP10ResponsesWithQuery() { return neverCacheHTTP10ResponsesWithQuery; } /** * Returns the maximum number of cache entries the cache will retain. */ public int getMaxCacheEntries() { return maxCacheEntries; } /** * Sets the maximum number of cache entries the cache will retain. * * @deprecated (4.3) use {@link Builder}. */ @Deprecated public void setMaxCacheEntries(final int maxCacheEntries) { this.maxCacheEntries = maxCacheEntries; } /** * Returns the number of times to retry a cache update on failure */ public int getMaxUpdateRetries(){ return maxUpdateRetries; } /** * Sets the number of times to retry a cache update on failure * * @deprecated (4.3) use {@link Builder}. */ @Deprecated public void setMaxUpdateRetries(final int maxUpdateRetries){ this.maxUpdateRetries = maxUpdateRetries; } /** * Returns whether 303 caching is enabled. * @return {@code true} if it is enabled. */ public boolean is303CachingEnabled() { return allow303Caching; } /** * Returns whether weak etags is allowed with PUT/DELETE methods. * @return {@code true} if it is allowed. */ public boolean isWeakETagOnPutDeleteAllowed() { return weakETagOnPutDeleteAllowed; } /** * Returns whether heuristic caching is enabled. * @return {@code true} if it is enabled. */ public boolean isHeuristicCachingEnabled() { return heuristicCachingEnabled; } /** * Enables or disables heuristic caching. * @param heuristicCachingEnabled should be {@code true} to * permit heuristic caching, {@code false} to disable it. * * @deprecated (4.3) use {@link Builder}. */ @Deprecated public void setHeuristicCachingEnabled(final boolean heuristicCachingEnabled) { this.heuristicCachingEnabled = heuristicCachingEnabled; } /** * Returns lifetime coefficient used in heuristic freshness caching. */ public float getHeuristicCoefficient() { return heuristicCoefficient; } /** * Sets coefficient to be used in heuristic freshness caching. This is * interpreted as the fraction of the time between the {@code Last-Modified} * and {@code Date} headers of a cached response during which the cached * response will be considered heuristically fresh. * @param heuristicCoefficient should be between {@code 0.0} and * {@code 1.0}. * * @deprecated (4.3) use {@link Builder}. */ @Deprecated public void setHeuristicCoefficient(final float heuristicCoefficient) { this.heuristicCoefficient = heuristicCoefficient; } /** * Get the default lifetime to be used if heuristic freshness calculation is * not possible. */ public long getHeuristicDefaultLifetime() { return heuristicDefaultLifetime; } /** * Sets default lifetime in seconds to be used if heuristic freshness * calculation is not possible. Explicit cache control directives on * either the request or origin response will override this, as will * the heuristic {@code Last-Modified} freshness calculation if it is * available. * @param heuristicDefaultLifetimeSecs is the number of seconds to * consider a cache-eligible response fresh in the absence of other * information. Set this to {@code 0} to disable this style of * heuristic caching. * * @deprecated (4.3) use {@link Builder}. */ @Deprecated public void setHeuristicDefaultLifetime(final long heuristicDefaultLifetimeSecs) { this.heuristicDefaultLifetime = heuristicDefaultLifetimeSecs; } /** * Returns whether the cache will behave as a shared cache or not. * @return {@code true} for a shared cache, {@code false} for a non- * shared (private) cache */ public boolean isSharedCache() { return isSharedCache; } /** * Sets whether the cache should behave as a shared cache or not. * @param isSharedCache true to behave as a shared cache, false to * behave as a non-shared (private) cache. To have the cache * behave like a browser cache, you want to set this to {@code false}. * * @deprecated (4.3) use {@link Builder}. */ @Deprecated public void setSharedCache(final boolean isSharedCache) { this.isSharedCache = isSharedCache; } /** * Returns the maximum number of threads to allow for background * revalidations due to the {@code stale-while-revalidate} directive. A * value of 0 means background revalidations are disabled. */ public int getAsynchronousWorkersMax() { return asynchronousWorkersMax; } /** * Sets the maximum number of threads to allow for background * revalidations due to the {@code stale-while-revalidate} directive. * @param max number of threads; a value of 0 disables background * revalidations. * * @deprecated (4.3) use {@link Builder}. */ @Deprecated public void setAsynchronousWorkersMax(final int max) { this.asynchronousWorkersMax = max; } /** * Returns the minimum number of threads to keep alive for background * revalidations due to the {@code stale-while-revalidate} directive. */ public int getAsynchronousWorkersCore() { return asynchronousWorkersCore; } /** * Sets the minimum number of threads to keep alive for background * revalidations due to the {@code stale-while-revalidate} directive. * @param min should be greater than zero and less than or equal * to getAsynchronousWorkersMax() * * @deprecated (4.3) use {@link Builder}. */ @Deprecated public void setAsynchronousWorkersCore(final int min) { this.asynchronousWorkersCore = min; } /** * Returns the current maximum idle lifetime in seconds for a * background revalidation worker thread. If a worker thread is idle * for this long, and there are more than the core number of worker * threads alive, the worker will be reclaimed. */ public int getAsynchronousWorkerIdleLifetimeSecs() { return asynchronousWorkerIdleLifetimeSecs; } /** * Sets the current maximum idle lifetime in seconds for a * background revalidation worker thread. If a worker thread is idle * for this long, and there are more than the core number of worker * threads alive, the worker will be reclaimed. * @param secs idle lifetime in seconds * * @deprecated (4.3) use {@link Builder}. */ @Deprecated public void setAsynchronousWorkerIdleLifetimeSecs(final int secs) { this.asynchronousWorkerIdleLifetimeSecs = secs; } /** * Returns the current maximum queue size for background revalidations. */ public int getRevalidationQueueSize() { return revalidationQueueSize; } /** * Sets the current maximum queue size for background revalidations. * * @deprecated (4.3) use {@link Builder}. */ @Deprecated public void setRevalidationQueueSize(final int size) { this.revalidationQueueSize = size; } @Override protected CacheConfig clone() throws CloneNotSupportedException { return (CacheConfig) super.clone(); } public static Builder custom() { return new Builder(); } public static Builder copy(final CacheConfig config) { Args.notNull(config, "Cache config"); return new Builder() .setMaxObjectSize(config.getMaxObjectSize()) .setMaxCacheEntries(config.getMaxCacheEntries()) .setMaxUpdateRetries(config.getMaxUpdateRetries()) .setHeuristicCachingEnabled(config.isHeuristicCachingEnabled()) .setHeuristicCoefficient(config.getHeuristicCoefficient()) .setHeuristicDefaultLifetime(config.getHeuristicDefaultLifetime()) .setSharedCache(config.isSharedCache()) .setAsynchronousWorkersMax(config.getAsynchronousWorkersMax()) .setAsynchronousWorkersCore(config.getAsynchronousWorkersCore()) .setAsynchronousWorkerIdleLifetimeSecs(config.getAsynchronousWorkerIdleLifetimeSecs()) .setRevalidationQueueSize(config.getRevalidationQueueSize()) .setNeverCacheHTTP10ResponsesWithQueryString(config.isNeverCacheHTTP10ResponsesWithQuery()); } public static class Builder { private long maxObjectSize; private int maxCacheEntries; private int maxUpdateRetries; private boolean allow303Caching; private boolean weakETagOnPutDeleteAllowed; private boolean heuristicCachingEnabled; private float heuristicCoefficient; private long heuristicDefaultLifetime; private boolean isSharedCache; private int asynchronousWorkersMax; private int asynchronousWorkersCore; private int asynchronousWorkerIdleLifetimeSecs; private int revalidationQueueSize; private boolean neverCacheHTTP10ResponsesWithQuery; Builder() { this.maxObjectSize = DEFAULT_MAX_OBJECT_SIZE_BYTES; this.maxCacheEntries = DEFAULT_MAX_CACHE_ENTRIES; this.maxUpdateRetries = DEFAULT_MAX_UPDATE_RETRIES; this.allow303Caching = DEFAULT_303_CACHING_ENABLED; this.weakETagOnPutDeleteAllowed = DEFAULT_WEAK_ETAG_ON_PUTDELETE_ALLOWED; this.heuristicCachingEnabled = false; this.heuristicCoefficient = DEFAULT_HEURISTIC_COEFFICIENT; this.heuristicDefaultLifetime = DEFAULT_HEURISTIC_LIFETIME; this.isSharedCache = true; this.asynchronousWorkersMax = DEFAULT_ASYNCHRONOUS_WORKERS_MAX; this.asynchronousWorkersCore = DEFAULT_ASYNCHRONOUS_WORKERS_CORE; this.asynchronousWorkerIdleLifetimeSecs = DEFAULT_ASYNCHRONOUS_WORKER_IDLE_LIFETIME_SECS; this.revalidationQueueSize = DEFAULT_REVALIDATION_QUEUE_SIZE; } /** * Specifies the maximum response body size that will be eligible for caching. * @param maxObjectSize size in bytes */ public Builder setMaxObjectSize(final long maxObjectSize) { this.maxObjectSize = maxObjectSize; return this; } /** * Sets the maximum number of cache entries the cache will retain. */ public Builder setMaxCacheEntries(final int maxCacheEntries) { this.maxCacheEntries = maxCacheEntries; return this; } /** * Sets the number of times to retry a cache update on failure */ public Builder setMaxUpdateRetries(final int maxUpdateRetries) { this.maxUpdateRetries = maxUpdateRetries; return this; } /** * Enables or disables 303 caching. * @param allow303Caching should be {@code true} to * permit 303 caching, {@code false} to disable it. */ public Builder setAllow303Caching(final boolean allow303Caching) { this.allow303Caching = allow303Caching; return this; } /** * Allows or disallows weak etags to be used with PUT/DELETE If-Match requests. * @param weakETagOnPutDeleteAllowed should be {@code true} to * permit weak etags, {@code false} to reject them. */ public Builder setWeakETagOnPutDeleteAllowed(final boolean weakETagOnPutDeleteAllowed) { this.weakETagOnPutDeleteAllowed = weakETagOnPutDeleteAllowed; return this; } /** * Enables or disables heuristic caching. * @param heuristicCachingEnabled should be {@code true} to * permit heuristic caching, {@code false} to enable it. */ public Builder setHeuristicCachingEnabled(final boolean heuristicCachingEnabled) { this.heuristicCachingEnabled = heuristicCachingEnabled; return this; } /** * Sets coefficient to be used in heuristic freshness caching. This is * interpreted as the fraction of the time between the {@code Last-Modified} * and {@code Date} headers of a cached response during which the cached * response will be considered heuristically fresh. * @param heuristicCoefficient should be between {@code 0.0} and * {@code 1.0}. */ public Builder setHeuristicCoefficient(final float heuristicCoefficient) { this.heuristicCoefficient = heuristicCoefficient; return this; } /** * Sets default lifetime in seconds to be used if heuristic freshness * calculation is not possible. Explicit cache control directives on * either the request or origin response will override this, as will * the heuristic {@code Last-Modified} freshness calculation if it is * available. * @param heuristicDefaultLifetime is the number of seconds to * consider a cache-eligible response fresh in the absence of other * information. Set this to {@code 0} to disable this style of * heuristic caching. */ public Builder setHeuristicDefaultLifetime(final long heuristicDefaultLifetime) { this.heuristicDefaultLifetime = heuristicDefaultLifetime; return this; } /** * Sets whether the cache should behave as a shared cache or not. * @param isSharedCache true to behave as a shared cache, false to * behave as a non-shared (private) cache. To have the cache * behave like a browser cache, you want to set this to {@code false}. */ public Builder setSharedCache(final boolean isSharedCache) { this.isSharedCache = isSharedCache; return this; } /** * Sets the maximum number of threads to allow for background * revalidations due to the {@code stale-while-revalidate} directive. * @param asynchronousWorkersMax number of threads; a value of 0 disables background * revalidations. */ public Builder setAsynchronousWorkersMax(final int asynchronousWorkersMax) { this.asynchronousWorkersMax = asynchronousWorkersMax; return this; } /** * Sets the minimum number of threads to keep alive for background * revalidations due to the {@code stale-while-revalidate} directive. * @param asynchronousWorkersCore should be greater than zero and less than or equal * to getAsynchronousWorkersMax() */ public Builder setAsynchronousWorkersCore(final int asynchronousWorkersCore) { this.asynchronousWorkersCore = asynchronousWorkersCore; return this; } /** * Sets the current maximum idle lifetime in seconds for a * background revalidation worker thread. If a worker thread is idle * for this long, and there are more than the core number of worker * threads alive, the worker will be reclaimed. * @param asynchronousWorkerIdleLifetimeSecs idle lifetime in seconds */ public Builder setAsynchronousWorkerIdleLifetimeSecs(final int asynchronousWorkerIdleLifetimeSecs) { this.asynchronousWorkerIdleLifetimeSecs = asynchronousWorkerIdleLifetimeSecs; return this; } /** * Sets the current maximum queue size for background revalidations. */ public Builder setRevalidationQueueSize(final int revalidationQueueSize) { this.revalidationQueueSize = revalidationQueueSize; return this; } /** * Sets whether the cache should never cache HTTP 1.0 responses with a query string or not. * @param neverCacheHTTP10ResponsesWithQuery true to never cache responses with a query * string, false to cache if explicit cache headers are found. Set this to {@code true} * to better emulate IE, which also never caches responses, regardless of what caching * headers may be present. */ public Builder setNeverCacheHTTP10ResponsesWithQueryString( final boolean neverCacheHTTP10ResponsesWithQuery) { this.neverCacheHTTP10ResponsesWithQuery = neverCacheHTTP10ResponsesWithQuery; return this; } public CacheConfig build() { return new CacheConfig( maxObjectSize, maxCacheEntries, maxUpdateRetries, allow303Caching, weakETagOnPutDeleteAllowed, heuristicCachingEnabled, heuristicCoefficient, heuristicDefaultLifetime, isSharedCache, asynchronousWorkersMax, asynchronousWorkersCore, asynchronousWorkerIdleLifetimeSecs, revalidationQueueSize, neverCacheHTTP10ResponsesWithQuery); } } @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append("[maxObjectSize=").append(this.maxObjectSize) .append(", maxCacheEntries=").append(this.maxCacheEntries) .append(", maxUpdateRetries=").append(this.maxUpdateRetries) .append(", 303CachingEnabled=").append(this.allow303Caching) .append(", weakETagOnPutDeleteAllowed=").append(this.weakETagOnPutDeleteAllowed) .append(", heuristicCachingEnabled=").append(this.heuristicCachingEnabled) .append(", heuristicCoefficient=").append(this.heuristicCoefficient) .append(", heuristicDefaultLifetime=").append(this.heuristicDefaultLifetime) .append(", isSharedCache=").append(this.isSharedCache) .append(", asynchronousWorkersMax=").append(this.asynchronousWorkersMax) .append(", asynchronousWorkersCore=").append(this.asynchronousWorkersCore) .append(", asynchronousWorkerIdleLifetimeSecs=").append(this.asynchronousWorkerIdleLifetimeSecs) .append(", revalidationQueueSize=").append(this.revalidationQueueSize) .append(", neverCacheHTTP10ResponsesWithQuery=").append(this.neverCacheHTTP10ResponsesWithQuery) .append("]"); return builder.toString(); } } ././@LongLink0100644 0000000 0000000 00000000176 12302131606 011631 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedHttpResponseGenerator.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedH0100644 0000000 0000000 00000014317 12301751724 032147 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.Date; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.utils.DateUtils; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpResponse; import org.apache.http.protocol.HTTP; /** * Rebuilds an {@link HttpResponse} from a {@link net.sf.ehcache.CacheEntry} * * @since 4.1 */ @Immutable class CachedHttpResponseGenerator { private final CacheValidityPolicy validityStrategy; CachedHttpResponseGenerator(final CacheValidityPolicy validityStrategy) { super(); this.validityStrategy = validityStrategy; } CachedHttpResponseGenerator() { this(new CacheValidityPolicy()); } /** * If I was able to use a {@link CacheEntity} to response to the {@link org.apache.http.HttpRequest} then * generate an {@link HttpResponse} based on the cache entry. * @param entry * {@link CacheEntity} to transform into an {@link HttpResponse} * @return {@link HttpResponse} that was constructed */ CloseableHttpResponse generateResponse(final HttpCacheEntry entry) { final Date now = new Date(); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, entry .getStatusCode(), entry.getReasonPhrase()); response.setHeaders(entry.getAllHeaders()); if (entry.getResource() != null) { final HttpEntity entity = new CacheEntity(entry); addMissingContentLengthHeader(response, entity); response.setEntity(entity); } final long age = this.validityStrategy.getCurrentAgeSecs(entry, now); if (age > 0) { if (age >= Integer.MAX_VALUE) { response.setHeader(HeaderConstants.AGE, "2147483648"); } else { response.setHeader(HeaderConstants.AGE, "" + ((int) age)); } } return Proxies.enhanceResponse(response); } /** * Generate a 304 - Not Modified response from a {@link CacheEntity}. This should be * used to respond to conditional requests, when the entry exists or has been re-validated. */ CloseableHttpResponse generateNotModifiedResponse(final HttpCacheEntry entry) { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); // The response MUST include the following headers // (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) // - Date, unless its omission is required by section 14.8.1 Header dateHeader = entry.getFirstHeader(HTTP.DATE_HEADER); if (dateHeader == null) { dateHeader = new BasicHeader(HTTP.DATE_HEADER, DateUtils.formatDate(new Date())); } response.addHeader(dateHeader); // - ETag and/or Content-Location, if the header would have been sent // in a 200 response to the same request final Header etagHeader = entry.getFirstHeader(HeaderConstants.ETAG); if (etagHeader != null) { response.addHeader(etagHeader); } final Header contentLocationHeader = entry.getFirstHeader("Content-Location"); if (contentLocationHeader != null) { response.addHeader(contentLocationHeader); } // - Expires, Cache-Control, and/or Vary, if the field-value might // differ from that sent in any previous response for the same // variant final Header expiresHeader = entry.getFirstHeader(HeaderConstants.EXPIRES); if (expiresHeader != null) { response.addHeader(expiresHeader); } final Header cacheControlHeader = entry.getFirstHeader(HeaderConstants.CACHE_CONTROL); if (cacheControlHeader != null) { response.addHeader(cacheControlHeader); } final Header varyHeader = entry.getFirstHeader(HeaderConstants.VARY); if (varyHeader != null) { response.addHeader(varyHeader); } return Proxies.enhanceResponse(response); } private void addMissingContentLengthHeader(final HttpResponse response, final HttpEntity entity) { if (transferEncodingIsPresent(response)) { return; } Header contentLength = response.getFirstHeader(HTTP.CONTENT_LEN); if (contentLength == null) { contentLength = new BasicHeader(HTTP.CONTENT_LEN, Long.toString(entity .getContentLength())); response.setHeader(contentLength); } } private boolean transferEncodingIsPresent(final HttpResponse response) { final Header hdr = response.getFirstHeader(HTTP.TRANSFER_ENCODING); return hdr != null; } } ././@LongLink0100644 0000000 0000000 00000000203 12302131606 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedResponseSuitabilityChecker.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedR0100644 0000000 0000000 00000033752 12301751724 032165 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.Date; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpStatus; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.utils.DateUtils; /** * Determines whether a given {@link HttpCacheEntry} is suitable to be * used as a response for a given {@link HttpRequest}. * * @since 4.1 */ @Immutable class CachedResponseSuitabilityChecker { private final Log log = LogFactory.getLog(getClass()); private final boolean sharedCache; private final boolean useHeuristicCaching; private final float heuristicCoefficient; private final long heuristicDefaultLifetime; private final CacheValidityPolicy validityStrategy; CachedResponseSuitabilityChecker(final CacheValidityPolicy validityStrategy, final CacheConfig config) { super(); this.validityStrategy = validityStrategy; this.sharedCache = config.isSharedCache(); this.useHeuristicCaching = config.isHeuristicCachingEnabled(); this.heuristicCoefficient = config.getHeuristicCoefficient(); this.heuristicDefaultLifetime = config.getHeuristicDefaultLifetime(); } CachedResponseSuitabilityChecker(final CacheConfig config) { this(new CacheValidityPolicy(), config); } private boolean isFreshEnough(final HttpCacheEntry entry, final HttpRequest request, final Date now) { if (validityStrategy.isResponseFresh(entry, now)) { return true; } if (useHeuristicCaching && validityStrategy.isResponseHeuristicallyFresh(entry, now, heuristicCoefficient, heuristicDefaultLifetime)) { return true; } if (originInsistsOnFreshness(entry)) { return false; } final long maxstale = getMaxStale(request); if (maxstale == -1) { return false; } return (maxstale > validityStrategy.getStalenessSecs(entry, now)); } private boolean originInsistsOnFreshness(final HttpCacheEntry entry) { if (validityStrategy.mustRevalidate(entry)) { return true; } if (!sharedCache) { return false; } return validityStrategy.proxyRevalidate(entry) || validityStrategy.hasCacheControlDirective(entry, "s-maxage"); } private long getMaxStale(final HttpRequest request) { long maxstale = -1; for(final Header h : request.getHeaders(HeaderConstants.CACHE_CONTROL)) { for(final HeaderElement elt : h.getElements()) { if (HeaderConstants.CACHE_CONTROL_MAX_STALE.equals(elt.getName())) { if ((elt.getValue() == null || "".equals(elt.getValue().trim())) && maxstale == -1) { maxstale = Long.MAX_VALUE; } else { try { long val = Long.parseLong(elt.getValue()); if (val < 0) { val = 0; } if (maxstale == -1 || val < maxstale) { maxstale = val; } } catch (final NumberFormatException nfe) { // err on the side of preserving semantic transparency maxstale = 0; } } } } } return maxstale; } /** * Determine if I can utilize a {@link HttpCacheEntry} to respond to the given * {@link HttpRequest} * * @param host * {@link HttpHost} * @param request * {@link HttpRequest} * @param entry * {@link HttpCacheEntry} * @param now * Right now in time * @return boolean yes/no answer */ public boolean canCachedResponseBeUsed(final HttpHost host, final HttpRequest request, final HttpCacheEntry entry, final Date now) { if (!isFreshEnough(entry, request, now)) { log.trace("Cache entry was not fresh enough"); return false; } if (!validityStrategy.contentLengthHeaderMatchesActualLength(entry)) { log.debug("Cache entry Content-Length and header information do not match"); return false; } if (hasUnsupportedConditionalHeaders(request)) { log.debug("Request contained conditional headers we don't handle"); return false; } if (!isConditional(request) && entry.getStatusCode() == HttpStatus.SC_NOT_MODIFIED) { return false; } if (isConditional(request) && !allConditionalsMatch(request, entry, now)) { return false; } for (final Header ccHdr : request.getHeaders(HeaderConstants.CACHE_CONTROL)) { for (final HeaderElement elt : ccHdr.getElements()) { if (HeaderConstants.CACHE_CONTROL_NO_CACHE.equals(elt.getName())) { log.trace("Response contained NO CACHE directive, cache was not suitable"); return false; } if (HeaderConstants.CACHE_CONTROL_NO_STORE.equals(elt.getName())) { log.trace("Response contained NO STORE directive, cache was not suitable"); return false; } if (HeaderConstants.CACHE_CONTROL_MAX_AGE.equals(elt.getName())) { try { final int maxage = Integer.parseInt(elt.getValue()); if (validityStrategy.getCurrentAgeSecs(entry, now) > maxage) { log.trace("Response from cache was NOT suitable due to max age"); return false; } } catch (final NumberFormatException ex) { // err conservatively log.debug("Response from cache was malformed" + ex.getMessage()); return false; } } if (HeaderConstants.CACHE_CONTROL_MAX_STALE.equals(elt.getName())) { try { final int maxstale = Integer.parseInt(elt.getValue()); if (validityStrategy.getFreshnessLifetimeSecs(entry) > maxstale) { log.trace("Response from cache was not suitable due to Max stale freshness"); return false; } } catch (final NumberFormatException ex) { // err conservatively log.debug("Response from cache was malformed: " + ex.getMessage()); return false; } } if (HeaderConstants.CACHE_CONTROL_MIN_FRESH.equals(elt.getName())) { try { final long minfresh = Long.parseLong(elt.getValue()); if (minfresh < 0L) { return false; } final long age = validityStrategy.getCurrentAgeSecs(entry, now); final long freshness = validityStrategy.getFreshnessLifetimeSecs(entry); if (freshness - age < minfresh) { log.trace("Response from cache was not suitable due to min fresh " + "freshness requirement"); return false; } } catch (final NumberFormatException ex) { // err conservatively log.debug("Response from cache was malformed: " + ex.getMessage()); return false; } } } } log.trace("Response from cache was suitable"); return true; } /** * Is this request the type of conditional request we support? * @param request The current httpRequest being made * @return {@code true} if the request is supported */ public boolean isConditional(final HttpRequest request) { return hasSupportedEtagValidator(request) || hasSupportedLastModifiedValidator(request); } /** * Check that conditionals that are part of this request match * @param request The current httpRequest being made * @param entry the cache entry * @param now right NOW in time * @return {@code true} if the request matches all conditionals */ public boolean allConditionalsMatch(final HttpRequest request, final HttpCacheEntry entry, final Date now) { final boolean hasEtagValidator = hasSupportedEtagValidator(request); final boolean hasLastModifiedValidator = hasSupportedLastModifiedValidator(request); final boolean etagValidatorMatches = (hasEtagValidator) && etagValidatorMatches(request, entry); final boolean lastModifiedValidatorMatches = (hasLastModifiedValidator) && lastModifiedValidatorMatches(request, entry, now); if ((hasEtagValidator && hasLastModifiedValidator) && !(etagValidatorMatches && lastModifiedValidatorMatches)) { return false; } else if (hasEtagValidator && !etagValidatorMatches) { return false; } if (hasLastModifiedValidator && !lastModifiedValidatorMatches) { return false; } return true; } private boolean hasUnsupportedConditionalHeaders(final HttpRequest request) { return (request.getFirstHeader(HeaderConstants.IF_RANGE) != null || request.getFirstHeader(HeaderConstants.IF_MATCH) != null || hasValidDateField(request, HeaderConstants.IF_UNMODIFIED_SINCE)); } private boolean hasSupportedEtagValidator(final HttpRequest request) { return request.containsHeader(HeaderConstants.IF_NONE_MATCH); } private boolean hasSupportedLastModifiedValidator(final HttpRequest request) { return hasValidDateField(request, HeaderConstants.IF_MODIFIED_SINCE); } /** * Check entry against If-None-Match * @param request The current httpRequest being made * @param entry the cache entry * @return boolean does the etag validator match */ private boolean etagValidatorMatches(final HttpRequest request, final HttpCacheEntry entry) { final Header etagHeader = entry.getFirstHeader(HeaderConstants.ETAG); final String etag = (etagHeader != null) ? etagHeader.getValue() : null; final Header[] ifNoneMatch = request.getHeaders(HeaderConstants.IF_NONE_MATCH); if (ifNoneMatch != null) { for (final Header h : ifNoneMatch) { for (final HeaderElement elt : h.getElements()) { final String reqEtag = elt.toString(); if (("*".equals(reqEtag) && etag != null) || reqEtag.equals(etag)) { return true; } } } } return false; } /** * Check entry against If-Modified-Since, if If-Modified-Since is in the future it is invalid as per * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html * @param request The current httpRequest being made * @param entry the cache entry * @param now right NOW in time * @return boolean Does the last modified header match */ private boolean lastModifiedValidatorMatches(final HttpRequest request, final HttpCacheEntry entry, final Date now) { final Header lastModifiedHeader = entry.getFirstHeader(HeaderConstants.LAST_MODIFIED); Date lastModified = null; if (lastModifiedHeader != null) { lastModified = DateUtils.parseDate(lastModifiedHeader.getValue()); } if (lastModified == null) { return false; } for (final Header h : request.getHeaders(HeaderConstants.IF_MODIFIED_SINCE)) { final Date ifModifiedSince = DateUtils.parseDate(h.getValue()); if (ifModifiedSince != null) { if (ifModifiedSince.after(now) || lastModified.after(ifModifiedSince)) { return false; } } } return true; } private boolean hasValidDateField(final HttpRequest request, final String headerName) { for(final Header h : request.getHeaders(headerName)) { final Date date = DateUtils.parseDate(h.getValue()); return date != null; } return false; } } ././@LongLink0100644 0000000 0000000 00000000156 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheEntity.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheEn0100644 0000000 0000000 00000005744 12301751724 032162 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Serializable; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.protocol.HTTP; import org.apache.http.util.Args; @Immutable class CacheEntity implements HttpEntity, Serializable { private static final long serialVersionUID = -3467082284120936233L; private final HttpCacheEntry cacheEntry; public CacheEntity(final HttpCacheEntry cacheEntry) { super(); this.cacheEntry = cacheEntry; } public Header getContentType() { return this.cacheEntry.getFirstHeader(HTTP.CONTENT_TYPE); } public Header getContentEncoding() { return this.cacheEntry.getFirstHeader(HTTP.CONTENT_ENCODING); } public boolean isChunked() { return false; } public boolean isRepeatable() { return true; } public long getContentLength() { return this.cacheEntry.getResource().length(); } public InputStream getContent() throws IOException { return this.cacheEntry.getResource().getInputStream(); } public void writeTo(final OutputStream outstream) throws IOException { Args.notNull(outstream, "Output stream"); final InputStream instream = this.cacheEntry.getResource().getInputStream(); try { IOUtils.copy(instream, outstream); } finally { instream.close(); } } public boolean isStreaming() { return false; } public void consumeContent() throws IOException { } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } } ././@LongLink0100644 0000000 0000000 00000000164 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheEntryUpdater.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheEn0100644 0000000 0000000 00000015254 12301751724 032157 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.ListIterator; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.Resource; import org.apache.http.client.cache.ResourceFactory; import org.apache.http.client.utils.DateUtils; import org.apache.http.protocol.HTTP; import org.apache.http.util.Args; /** * Update a {@link HttpCacheEntry} with new or updated information based on the latest * 304 status response from the Server. Use the {@link HttpResponse} to perform * the update. * * @since 4.1 */ @Immutable class CacheEntryUpdater { private final ResourceFactory resourceFactory; CacheEntryUpdater() { this(new HeapResourceFactory()); } CacheEntryUpdater(final ResourceFactory resourceFactory) { super(); this.resourceFactory = resourceFactory; } /** * Update the entry with the new information from the response. Should only be used for * 304 responses. * * @param requestId * @param entry The cache Entry to be updated * @param requestDate When the request was performed * @param responseDate When the response was gotten * @param response The HttpResponse from the backend server call * @return HttpCacheEntry an updated version of the cache entry * @throws java.io.IOException if something bad happens while trying to read the body from the original entry */ public HttpCacheEntry updateCacheEntry( final String requestId, final HttpCacheEntry entry, final Date requestDate, final Date responseDate, final HttpResponse response) throws IOException { Args.check(response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_MODIFIED, "Response must have 304 status code"); final Header[] mergedHeaders = mergeHeaders(entry, response); Resource resource = null; if (entry.getResource() != null) { resource = resourceFactory.copy(requestId, entry.getResource()); } return new HttpCacheEntry( requestDate, responseDate, entry.getStatusLine(), mergedHeaders, resource); } protected Header[] mergeHeaders(final HttpCacheEntry entry, final HttpResponse response) { if (entryAndResponseHaveDateHeader(entry, response) && entryDateHeaderNewerThenResponse(entry, response)) { // Don't merge headers, keep the entry's headers as they are newer. return entry.getAllHeaders(); } final List

cacheEntryHeaderList = new ArrayList
(Arrays.asList(entry .getAllHeaders())); removeCacheHeadersThatMatchResponse(cacheEntryHeaderList, response); removeCacheEntry1xxWarnings(cacheEntryHeaderList, entry); cacheEntryHeaderList.addAll(Arrays.asList(response.getAllHeaders())); return cacheEntryHeaderList.toArray(new Header[cacheEntryHeaderList.size()]); } private void removeCacheHeadersThatMatchResponse(final List
cacheEntryHeaderList, final HttpResponse response) { for (final Header responseHeader : response.getAllHeaders()) { final ListIterator
cacheEntryHeaderListIter = cacheEntryHeaderList.listIterator(); while (cacheEntryHeaderListIter.hasNext()) { final String cacheEntryHeaderName = cacheEntryHeaderListIter.next().getName(); if (cacheEntryHeaderName.equals(responseHeader.getName())) { cacheEntryHeaderListIter.remove(); } } } } private void removeCacheEntry1xxWarnings(final List
cacheEntryHeaderList, final HttpCacheEntry entry) { final ListIterator
cacheEntryHeaderListIter = cacheEntryHeaderList.listIterator(); while (cacheEntryHeaderListIter.hasNext()) { final String cacheEntryHeaderName = cacheEntryHeaderListIter.next().getName(); if (HeaderConstants.WARNING.equals(cacheEntryHeaderName)) { for (final Header cacheEntryWarning : entry.getHeaders(HeaderConstants.WARNING)) { if (cacheEntryWarning.getValue().startsWith("1")) { cacheEntryHeaderListIter.remove(); } } } } } private boolean entryDateHeaderNewerThenResponse(final HttpCacheEntry entry, final HttpResponse response) { final Date entryDate = DateUtils.parseDate(entry.getFirstHeader(HTTP.DATE_HEADER) .getValue()); final Date responseDate = DateUtils.parseDate(response.getFirstHeader(HTTP.DATE_HEADER) .getValue()); if (entryDate == null || responseDate == null) { return false; } if (!entryDate.after(responseDate)) { return false; } return true; } private boolean entryAndResponseHaveDateHeader(final HttpCacheEntry entry, final HttpResponse response) { if (entry.getFirstHeader(HTTP.DATE_HEADER) != null && response.getFirstHeader(HTTP.DATE_HEADER) != null) { return true; } return false; } } ././@LongLink0100644 0000000 0000000 00000000163 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheInvalidator.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheIn0100644 0000000 0000000 00000024251 12301751722 032156 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.Date; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheInvalidator; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.client.utils.DateUtils; import org.apache.http.protocol.HTTP; /** * Given a particular HttpRequest, flush any cache entries that this request * would invalidate. * * @since 4.1 */ @Immutable class CacheInvalidator implements HttpCacheInvalidator { private final HttpCacheStorage storage; private final CacheKeyGenerator cacheKeyGenerator; private final Log log = LogFactory.getLog(getClass()); /** * Create a new {@link CacheInvalidator} for a given {@link HttpCache} and * {@link CacheKeyGenerator}. * * @param uriExtractor Provides identifiers for the keys to store cache entries * @param storage the cache to store items away in */ public CacheInvalidator( final CacheKeyGenerator uriExtractor, final HttpCacheStorage storage) { this.cacheKeyGenerator = uriExtractor; this.storage = storage; } /** * Remove cache entries from the cache that are no longer fresh or * have been invalidated in some way. * * @param host The backend host we are talking to * @param req The HttpRequest to that host */ public void flushInvalidatedCacheEntries(final HttpHost host, final HttpRequest req) { if (requestShouldNotBeCached(req)) { log.debug("Request should not be cached"); final String theUri = cacheKeyGenerator.getURI(host, req); final HttpCacheEntry parent = getEntry(theUri); log.debug("parent entry: " + parent); if (parent != null) { for (final String variantURI : parent.getVariantMap().values()) { flushEntry(variantURI); } flushEntry(theUri); } final URL reqURL = getAbsoluteURL(theUri); if (reqURL == null) { log.error("Couldn't transform request into valid URL"); return; } final Header clHdr = req.getFirstHeader("Content-Location"); if (clHdr != null) { final String contentLocation = clHdr.getValue(); if (!flushAbsoluteUriFromSameHost(reqURL, contentLocation)) { flushRelativeUriFromSameHost(reqURL, contentLocation); } } final Header lHdr = req.getFirstHeader("Location"); if (lHdr != null) { flushAbsoluteUriFromSameHost(reqURL, lHdr.getValue()); } } } private void flushEntry(final String uri) { try { storage.removeEntry(uri); } catch (final IOException ioe) { log.warn("unable to flush cache entry", ioe); } } private HttpCacheEntry getEntry(final String theUri) { try { return storage.getEntry(theUri); } catch (final IOException ioe) { log.warn("could not retrieve entry from storage", ioe); } return null; } protected void flushUriIfSameHost(final URL requestURL, final URL targetURL) { final URL canonicalTarget = getAbsoluteURL(cacheKeyGenerator.canonicalizeUri(targetURL.toString())); if (canonicalTarget == null) { return; } if (canonicalTarget.getAuthority().equalsIgnoreCase(requestURL.getAuthority())) { flushEntry(canonicalTarget.toString()); } } protected void flushRelativeUriFromSameHost(final URL reqURL, final String relUri) { final URL relURL = getRelativeURL(reqURL, relUri); if (relURL == null) { return; } flushUriIfSameHost(reqURL, relURL); } protected boolean flushAbsoluteUriFromSameHost(final URL reqURL, final String uri) { final URL absURL = getAbsoluteURL(uri); if (absURL == null) { return false; } flushUriIfSameHost(reqURL,absURL); return true; } private URL getAbsoluteURL(final String uri) { URL absURL = null; try { absURL = new URL(uri); } catch (final MalformedURLException mue) { // nop } return absURL; } private URL getRelativeURL(final URL reqURL, final String relUri) { URL relURL = null; try { relURL = new URL(reqURL,relUri); } catch (final MalformedURLException e) { // nop } return relURL; } protected boolean requestShouldNotBeCached(final HttpRequest req) { final String method = req.getRequestLine().getMethod(); return notGetOrHeadRequest(method); } private boolean notGetOrHeadRequest(final String method) { return !(HeaderConstants.GET_METHOD.equals(method) || HeaderConstants.HEAD_METHOD .equals(method)); } /** Flushes entries that were invalidated by the given response * received for the given host/request pair. */ public void flushInvalidatedCacheEntries(final HttpHost host, final HttpRequest request, final HttpResponse response) { final int status = response.getStatusLine().getStatusCode(); if (status < 200 || status > 299) { return; } final URL reqURL = getAbsoluteURL(cacheKeyGenerator.getURI(host, request)); if (reqURL == null) { return; } final URL contentLocation = getContentLocationURL(reqURL, response); if (contentLocation != null) { flushLocationCacheEntry(reqURL, response, contentLocation); } final URL location = getLocationURL(reqURL, response); if (location != null) { flushLocationCacheEntry(reqURL, response, location); } } private void flushLocationCacheEntry(final URL reqURL, final HttpResponse response, final URL location) { final String cacheKey = cacheKeyGenerator.canonicalizeUri(location.toString()); final HttpCacheEntry entry = getEntry(cacheKey); if (entry == null) { return; } // do not invalidate if response is strictly older than entry // or if the etags match if (responseDateOlderThanEntryDate(response, entry)) { return; } if (!responseAndEntryEtagsDiffer(response, entry)) { return; } flushUriIfSameHost(reqURL, location); } private URL getContentLocationURL(final URL reqURL, final HttpResponse response) { final Header clHeader = response.getFirstHeader("Content-Location"); if (clHeader == null) { return null; } final String contentLocation = clHeader.getValue(); final URL canonURL = getAbsoluteURL(contentLocation); if (canonURL != null) { return canonURL; } return getRelativeURL(reqURL, contentLocation); } private URL getLocationURL(final URL reqURL, final HttpResponse response) { final Header clHeader = response.getFirstHeader("Location"); if (clHeader == null) { return null; } final String location = clHeader.getValue(); final URL canonURL = getAbsoluteURL(location); if (canonURL != null) { return canonURL; } return getRelativeURL(reqURL, location); } private boolean responseAndEntryEtagsDiffer(final HttpResponse response, final HttpCacheEntry entry) { final Header entryEtag = entry.getFirstHeader(HeaderConstants.ETAG); final Header responseEtag = response.getFirstHeader(HeaderConstants.ETAG); if (entryEtag == null || responseEtag == null) { return false; } return (!entryEtag.getValue().equals(responseEtag.getValue())); } private boolean responseDateOlderThanEntryDate(final HttpResponse response, final HttpCacheEntry entry) { final Header entryDateHeader = entry.getFirstHeader(HTTP.DATE_HEADER); final Header responseDateHeader = response.getFirstHeader(HTTP.DATE_HEADER); if (entryDateHeader == null || responseDateHeader == null) { /* be conservative; should probably flush */ return false; } final Date entryDate = DateUtils.parseDate(entryDateHeader.getValue()); final Date responseDate = DateUtils.parseDate(responseDateHeader.getValue()); if (entryDate == null || responseDate == null) { return false; } return responseDate.before(entryDate); } } ././@LongLink0100644 0000000 0000000 00000000164 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheKeyGenerator.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheKe0100644 0000000 0000000 00000014777 12301751720 032161 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.http.Consts; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.utils.URIUtils; /** * @since 4.1 */ @Immutable class CacheKeyGenerator { private static final URI BASE_URI = URI.create("http://example.com/"); /** * For a given {@link HttpHost} and {@link HttpRequest} get a URI from the * pair that I can use as an identifier KEY into my HttpCache * * @param host The host for this request * @param req the {@link HttpRequest} * @return String the extracted URI */ public String getURI(final HttpHost host, final HttpRequest req) { if (isRelativeRequest(req)) { return canonicalizeUri(String.format("%s%s", host.toString(), req.getRequestLine().getUri())); } return canonicalizeUri(req.getRequestLine().getUri()); } public String canonicalizeUri(final String uri) { try { final URI normalized = URIUtils.resolve(BASE_URI, uri); final URL u = new URL(normalized.toASCIIString()); final String protocol = u.getProtocol(); final String hostname = u.getHost(); final int port = canonicalizePort(u.getPort(), protocol); final String path = u.getPath(); final String query = u.getQuery(); final String file = (query != null) ? (path + "?" + query) : path; final URL out = new URL(protocol, hostname, port, file); return out.toString(); } catch (final IllegalArgumentException e) { return uri; } catch (final MalformedURLException e) { return uri; } } private int canonicalizePort(final int port, final String protocol) { if (port == -1 && "http".equalsIgnoreCase(protocol)) { return 80; } else if (port == -1 && "https".equalsIgnoreCase(protocol)) { return 443; } return port; } private boolean isRelativeRequest(final HttpRequest req) { final String requestUri = req.getRequestLine().getUri(); return ("*".equals(requestUri) || requestUri.startsWith("/")); } protected String getFullHeaderValue(final Header[] headers) { if (headers == null) { return ""; } final StringBuilder buf = new StringBuilder(""); boolean first = true; for (final Header hdr : headers) { if (!first) { buf.append(", "); } buf.append(hdr.getValue().trim()); first = false; } return buf.toString(); } /** * For a given {@link HttpHost} and {@link HttpRequest} if the request has a * VARY header - I need to get an additional URI from the pair of host and * request so that I can also store the variant into my HttpCache. * * @param host The host for this request * @param req the {@link HttpRequest} * @param entry the parent entry used to track the variants * @return String the extracted variant URI */ public String getVariantURI(final HttpHost host, final HttpRequest req, final HttpCacheEntry entry) { if (!entry.hasVariants()) { return getURI(host, req); } return getVariantKey(req, entry) + getURI(host, req); } /** * Compute a "variant key" from the headers of a given request that are * covered by the Vary header of a given cache entry. Any request whose * varying headers match those of this request should have the same * variant key. * @param req originating request * @param entry cache entry in question that has variants * @return a String variant key */ public String getVariantKey(final HttpRequest req, final HttpCacheEntry entry) { final List variantHeaderNames = new ArrayList(); for (final Header varyHdr : entry.getHeaders(HeaderConstants.VARY)) { for (final HeaderElement elt : varyHdr.getElements()) { variantHeaderNames.add(elt.getName()); } } Collections.sort(variantHeaderNames); StringBuilder buf; try { buf = new StringBuilder("{"); boolean first = true; for (final String headerName : variantHeaderNames) { if (!first) { buf.append("&"); } buf.append(URLEncoder.encode(headerName, Consts.UTF_8.name())); buf.append("="); buf.append(URLEncoder.encode(getFullHeaderValue(req.getHeaders(headerName)), Consts.UTF_8.name())); first = false; } buf.append("}"); } catch (final UnsupportedEncodingException uee) { throw new RuntimeException("couldn't encode to UTF-8", uee); } return buf.toString(); } } ././@LongLink0100644 0000000 0000000 00000000153 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheMap.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheMa0100644 0000000 0000000 00000003366 12301751724 032153 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.LinkedHashMap; import java.util.Map; import org.apache.http.client.cache.HttpCacheEntry; final class CacheMap extends LinkedHashMap { private static final long serialVersionUID = -7750025207539768511L; private final int maxEntries; CacheMap(final int maxEntries) { super(20, 0.75f, true); this.maxEntries = maxEntries; } @Override protected boolean removeEldestEntry(final Map.Entry eldest) { return size() > this.maxEntries; } } ././@LongLink0100644 0000000 0000000 00000000166 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheVa0100644 0000000 0000000 00000027360 12301751722 032162 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.Date; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpRequest; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.utils.DateUtils; import org.apache.http.protocol.HTTP; /** * @since 4.1 */ @Immutable class CacheValidityPolicy { public static final long MAX_AGE = 2147483648L; CacheValidityPolicy() { super(); } public long getCurrentAgeSecs(final HttpCacheEntry entry, final Date now) { return getCorrectedInitialAgeSecs(entry) + getResidentTimeSecs(entry, now); } public long getFreshnessLifetimeSecs(final HttpCacheEntry entry) { final long maxage = getMaxAge(entry); if (maxage > -1) { return maxage; } final Date dateValue = entry.getDate(); if (dateValue == null) { return 0L; } final Date expiry = getExpirationDate(entry); if (expiry == null) { return 0; } final long diff = expiry.getTime() - dateValue.getTime(); return (diff / 1000); } public boolean isResponseFresh(final HttpCacheEntry entry, final Date now) { return (getCurrentAgeSecs(entry, now) < getFreshnessLifetimeSecs(entry)); } /** * Decides if this response is fresh enough based Last-Modified and Date, if available. * This entry is meant to be used when isResponseFresh returns false. The algorithm is as follows: * * if last-modified and date are defined, freshness lifetime is coefficient*(date-lastModified), * else freshness lifetime is defaultLifetime * * @param entry the cache entry * @param now what time is it currently (When is right NOW) * @param coefficient Part of the heuristic for cache entry freshness * @param defaultLifetime How long can I assume a cache entry is default TTL * @return {@code true} if the response is fresh */ public boolean isResponseHeuristicallyFresh(final HttpCacheEntry entry, final Date now, final float coefficient, final long defaultLifetime) { return (getCurrentAgeSecs(entry, now) < getHeuristicFreshnessLifetimeSecs(entry, coefficient, defaultLifetime)); } public long getHeuristicFreshnessLifetimeSecs(final HttpCacheEntry entry, final float coefficient, final long defaultLifetime) { final Date dateValue = entry.getDate(); final Date lastModifiedValue = getLastModifiedValue(entry); if (dateValue != null && lastModifiedValue != null) { final long diff = dateValue.getTime() - lastModifiedValue.getTime(); if (diff < 0) { return 0; } return (long)(coefficient * (diff / 1000)); } return defaultLifetime; } public boolean isRevalidatable(final HttpCacheEntry entry) { return entry.getFirstHeader(HeaderConstants.ETAG) != null || entry.getFirstHeader(HeaderConstants.LAST_MODIFIED) != null; } public boolean mustRevalidate(final HttpCacheEntry entry) { return hasCacheControlDirective(entry, HeaderConstants.CACHE_CONTROL_MUST_REVALIDATE); } public boolean proxyRevalidate(final HttpCacheEntry entry) { return hasCacheControlDirective(entry, HeaderConstants.CACHE_CONTROL_PROXY_REVALIDATE); } public boolean mayReturnStaleWhileRevalidating(final HttpCacheEntry entry, final Date now) { for (final Header h : entry.getHeaders(HeaderConstants.CACHE_CONTROL)) { for(final HeaderElement elt : h.getElements()) { if (HeaderConstants.STALE_WHILE_REVALIDATE.equalsIgnoreCase(elt.getName())) { try { final int allowedStalenessLifetime = Integer.parseInt(elt.getValue()); if (getStalenessSecs(entry, now) <= allowedStalenessLifetime) { return true; } } catch (final NumberFormatException nfe) { // skip malformed directive } } } } return false; } public boolean mayReturnStaleIfError(final HttpRequest request, final HttpCacheEntry entry, final Date now) { final long stalenessSecs = getStalenessSecs(entry, now); return mayReturnStaleIfError(request.getHeaders(HeaderConstants.CACHE_CONTROL), stalenessSecs) || mayReturnStaleIfError(entry.getHeaders(HeaderConstants.CACHE_CONTROL), stalenessSecs); } private boolean mayReturnStaleIfError(final Header[] headers, final long stalenessSecs) { boolean result = false; for(final Header h : headers) { for(final HeaderElement elt : h.getElements()) { if (HeaderConstants.STALE_IF_ERROR.equals(elt.getName())) { try { final int staleIfErrorSecs = Integer.parseInt(elt.getValue()); if (stalenessSecs <= staleIfErrorSecs) { result = true; break; } } catch (final NumberFormatException nfe) { // skip malformed directive } } } } return result; } /** * @deprecated (4.3) use {@link HttpCacheEntry#getDate()}. * @param entry * @return */ @Deprecated protected Date getDateValue(final HttpCacheEntry entry) { return entry.getDate(); } protected Date getLastModifiedValue(final HttpCacheEntry entry) { final Header dateHdr = entry.getFirstHeader(HeaderConstants.LAST_MODIFIED); if (dateHdr == null) { return null; } return DateUtils.parseDate(dateHdr.getValue()); } protected long getContentLengthValue(final HttpCacheEntry entry) { final Header cl = entry.getFirstHeader(HTTP.CONTENT_LEN); if (cl == null) { return -1; } try { return Long.parseLong(cl.getValue()); } catch (final NumberFormatException ex) { return -1; } } protected boolean hasContentLengthHeader(final HttpCacheEntry entry) { return null != entry.getFirstHeader(HTTP.CONTENT_LEN); } /** * This matters for deciding whether the cache entry is valid to serve as a * response. If these values do not match, we might have a partial response * * @param entry The cache entry we are currently working with * @return boolean indicating whether actual length matches Content-Length */ protected boolean contentLengthHeaderMatchesActualLength(final HttpCacheEntry entry) { return !hasContentLengthHeader(entry) || getContentLengthValue(entry) == entry.getResource().length(); } protected long getApparentAgeSecs(final HttpCacheEntry entry) { final Date dateValue = entry.getDate(); if (dateValue == null) { return MAX_AGE; } final long diff = entry.getResponseDate().getTime() - dateValue.getTime(); if (diff < 0L) { return 0; } return (diff / 1000); } protected long getAgeValue(final HttpCacheEntry entry) { long ageValue = 0; for (final Header hdr : entry.getHeaders(HeaderConstants.AGE)) { long hdrAge; try { hdrAge = Long.parseLong(hdr.getValue()); if (hdrAge < 0) { hdrAge = MAX_AGE; } } catch (final NumberFormatException nfe) { hdrAge = MAX_AGE; } ageValue = (hdrAge > ageValue) ? hdrAge : ageValue; } return ageValue; } protected long getCorrectedReceivedAgeSecs(final HttpCacheEntry entry) { final long apparentAge = getApparentAgeSecs(entry); final long ageValue = getAgeValue(entry); return (apparentAge > ageValue) ? apparentAge : ageValue; } protected long getResponseDelaySecs(final HttpCacheEntry entry) { final long diff = entry.getResponseDate().getTime() - entry.getRequestDate().getTime(); return (diff / 1000L); } protected long getCorrectedInitialAgeSecs(final HttpCacheEntry entry) { return getCorrectedReceivedAgeSecs(entry) + getResponseDelaySecs(entry); } protected long getResidentTimeSecs(final HttpCacheEntry entry, final Date now) { final long diff = now.getTime() - entry.getResponseDate().getTime(); return (diff / 1000L); } protected long getMaxAge(final HttpCacheEntry entry) { long maxage = -1; for (final Header hdr : entry.getHeaders(HeaderConstants.CACHE_CONTROL)) { for (final HeaderElement elt : hdr.getElements()) { if (HeaderConstants.CACHE_CONTROL_MAX_AGE.equals(elt.getName()) || "s-maxage".equals(elt.getName())) { try { final long currMaxAge = Long.parseLong(elt.getValue()); if (maxage == -1 || currMaxAge < maxage) { maxage = currMaxAge; } } catch (final NumberFormatException nfe) { // be conservative if can't parse maxage = 0; } } } } return maxage; } protected Date getExpirationDate(final HttpCacheEntry entry) { final Header expiresHeader = entry.getFirstHeader(HeaderConstants.EXPIRES); if (expiresHeader == null) { return null; } return DateUtils.parseDate(expiresHeader.getValue()); } public boolean hasCacheControlDirective(final HttpCacheEntry entry, final String directive) { for (final Header h : entry.getHeaders(HeaderConstants.CACHE_CONTROL)) { for(final HeaderElement elt : h.getElements()) { if (directive.equalsIgnoreCase(elt.getName())) { return true; } } } return false; } public long getStalenessSecs(final HttpCacheEntry entry, final Date now) { final long age = getCurrentAgeSecs(entry, now); final long freshness = getFreshnessLifetimeSecs(entry); if (age <= freshness) { return 0L; } return (age - freshness); } } ././@LongLink0100644 0000000 0000000 00000000156 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingExec.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Caching0100644 0000000 0000000 00000111177 12301751723 032225 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpMessage; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.ProtocolVersion; import org.apache.http.RequestLine; import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.cache.CacheResponseStatus; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheContext; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.client.cache.ResourceFactory; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.DateUtils; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.impl.execchain.ClientExecChain; import org.apache.http.message.BasicHttpResponse; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.VersionInfo; /** * Request executor in the request execution chain that is responsible for * transparent client-side caching. The current implementation is conditionally * compliant with HTTP/1.1 (meaning all the MUST and MUST NOTs are obeyed), * although quite a lot, though not all, of the SHOULDs and SHOULD NOTs * are obeyed too. *

* Folks that would like to experiment with alternative storage backends * should look at the {@link HttpCacheStorage} interface and the related * package documentation there. You may also be interested in the provided * {@link org.apache.http.impl.client.cache.ehcache.EhcacheHttpCacheStorage * EhCache} and {@link * org.apache.http.impl.client.cache.memcached.MemcachedHttpCacheStorage * memcached} storage backends. *

* Further responsibilities such as communication with the opposite * endpoint is delegated to the next executor in the request execution * chain. * * @since 4.3 */ @ThreadSafe // So long as the responseCache implementation is threadsafe public class CachingExec implements ClientExecChain { private final static boolean SUPPORTS_RANGE_AND_CONTENT_RANGE_HEADERS = false; private final AtomicLong cacheHits = new AtomicLong(); private final AtomicLong cacheMisses = new AtomicLong(); private final AtomicLong cacheUpdates = new AtomicLong(); private final Map viaHeaders = new HashMap(4); private final CacheConfig cacheConfig; private final ClientExecChain backend; private final HttpCache responseCache; private final CacheValidityPolicy validityPolicy; private final CachedHttpResponseGenerator responseGenerator; private final CacheableRequestPolicy cacheableRequestPolicy; private final CachedResponseSuitabilityChecker suitabilityChecker; private final ConditionalRequestBuilder conditionalRequestBuilder; private final ResponseProtocolCompliance responseCompliance; private final RequestProtocolCompliance requestCompliance; private final ResponseCachingPolicy responseCachingPolicy; private final AsynchronousValidator asynchRevalidator; private final Log log = LogFactory.getLog(getClass()); public CachingExec( final ClientExecChain backend, final HttpCache cache, final CacheConfig config) { this(backend, cache, config, null); } public CachingExec( final ClientExecChain backend, final HttpCache cache, final CacheConfig config, final AsynchronousValidator asynchRevalidator) { super(); Args.notNull(backend, "HTTP backend"); Args.notNull(cache, "HttpCache"); this.cacheConfig = config != null ? config : CacheConfig.DEFAULT; this.backend = backend; this.responseCache = cache; this.validityPolicy = new CacheValidityPolicy(); this.responseGenerator = new CachedHttpResponseGenerator(this.validityPolicy); this.cacheableRequestPolicy = new CacheableRequestPolicy(); this.suitabilityChecker = new CachedResponseSuitabilityChecker(this.validityPolicy, config); this.conditionalRequestBuilder = new ConditionalRequestBuilder(); this.responseCompliance = new ResponseProtocolCompliance(); this.requestCompliance = new RequestProtocolCompliance(config.isWeakETagOnPutDeleteAllowed()); this.responseCachingPolicy = new ResponseCachingPolicy( this.cacheConfig.getMaxObjectSize(), this.cacheConfig.isSharedCache(), this.cacheConfig.isNeverCacheHTTP10ResponsesWithQuery(), this.cacheConfig.is303CachingEnabled()); this.asynchRevalidator = asynchRevalidator; } public CachingExec( final ClientExecChain backend, final ResourceFactory resourceFactory, final HttpCacheStorage storage, final CacheConfig config) { this(backend, new BasicHttpCache(resourceFactory, storage, config), config); } public CachingExec(final ClientExecChain backend) { this(backend, new BasicHttpCache(), CacheConfig.DEFAULT); } CachingExec( final ClientExecChain backend, final HttpCache responseCache, final CacheValidityPolicy validityPolicy, final ResponseCachingPolicy responseCachingPolicy, final CachedHttpResponseGenerator responseGenerator, final CacheableRequestPolicy cacheableRequestPolicy, final CachedResponseSuitabilityChecker suitabilityChecker, final ConditionalRequestBuilder conditionalRequestBuilder, final ResponseProtocolCompliance responseCompliance, final RequestProtocolCompliance requestCompliance, final CacheConfig config, final AsynchronousValidator asynchRevalidator) { this.cacheConfig = config != null ? config : CacheConfig.DEFAULT; this.backend = backend; this.responseCache = responseCache; this.validityPolicy = validityPolicy; this.responseCachingPolicy = responseCachingPolicy; this.responseGenerator = responseGenerator; this.cacheableRequestPolicy = cacheableRequestPolicy; this.suitabilityChecker = suitabilityChecker; this.conditionalRequestBuilder = conditionalRequestBuilder; this.responseCompliance = responseCompliance; this.requestCompliance = requestCompliance; this.asynchRevalidator = asynchRevalidator; } /** * Reports the number of times that the cache successfully responded * to an {@link HttpRequest} without contacting the origin server. * @return the number of cache hits */ public long getCacheHits() { return cacheHits.get(); } /** * Reports the number of times that the cache contacted the origin * server because it had no appropriate response cached. * @return the number of cache misses */ public long getCacheMisses() { return cacheMisses.get(); } /** * Reports the number of times that the cache was able to satisfy * a response by revalidating an existing but stale cache entry. * @return the number of cache revalidations */ public long getCacheUpdates() { return cacheUpdates.get(); } public CloseableHttpResponse execute( final HttpRoute route, final HttpRequestWrapper request) throws IOException, HttpException { return execute(route, request, HttpClientContext.create(), null); } public CloseableHttpResponse execute( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context) throws IOException, HttpException { return execute(route, request, context, null); } public CloseableHttpResponse execute( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware) throws IOException, HttpException { final HttpHost target = context.getTargetHost(); final String via = generateViaHeader(request.getOriginal()); // default response context setResponseStatus(context, CacheResponseStatus.CACHE_MISS); if (clientRequestsOurOptions(request)) { setResponseStatus(context, CacheResponseStatus.CACHE_MODULE_RESPONSE); return Proxies.enhanceResponse(new OptionsHttp11Response()); } final HttpResponse fatalErrorResponse = getFatallyNoncompliantResponse(request, context); if (fatalErrorResponse != null) { return Proxies.enhanceResponse(fatalErrorResponse); } requestCompliance.makeRequestCompliant(request); request.addHeader("Via",via); flushEntriesInvalidatedByRequest(context.getTargetHost(), request); if (!cacheableRequestPolicy.isServableFromCache(request)) { log.debug("Request is not servable from cache"); return callBackend(route, request, context, execAware); } final HttpCacheEntry entry = satisfyFromCache(target, request); if (entry == null) { log.debug("Cache miss"); return handleCacheMiss(route, request, context, execAware); } else { return handleCacheHit(route, request, context, execAware, entry); } } private CloseableHttpResponse handleCacheHit( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware, final HttpCacheEntry entry) throws IOException, HttpException { final HttpHost target = context.getTargetHost(); recordCacheHit(target, request); CloseableHttpResponse out = null; final Date now = getCurrentDate(); if (suitabilityChecker.canCachedResponseBeUsed(target, request, entry, now)) { log.debug("Cache hit"); out = generateCachedResponse(request, context, entry, now); } else if (!mayCallBackend(request)) { log.debug("Cache entry not suitable but only-if-cached requested"); out = generateGatewayTimeout(context); } else if (!(entry.getStatusCode() == HttpStatus.SC_NOT_MODIFIED && !suitabilityChecker.isConditional(request))) { log.debug("Revalidating cache entry"); return revalidateCacheEntry(route, request, context, execAware, entry, now); } else { log.debug("Cache entry not usable; calling backend"); return callBackend(route, request, context, execAware); } context.setAttribute(HttpClientContext.HTTP_ROUTE, route); context.setAttribute(HttpClientContext.HTTP_TARGET_HOST, target); context.setAttribute(HttpClientContext.HTTP_REQUEST, request); context.setAttribute(HttpClientContext.HTTP_RESPONSE, out); context.setAttribute(HttpClientContext.HTTP_REQ_SENT, Boolean.TRUE); return out; } private CloseableHttpResponse revalidateCacheEntry( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware, final HttpCacheEntry entry, final Date now) throws HttpException { try { if (asynchRevalidator != null && !staleResponseNotAllowed(request, entry, now) && validityPolicy.mayReturnStaleWhileRevalidating(entry, now)) { log.trace("Serving stale with asynchronous revalidation"); final CloseableHttpResponse resp = generateCachedResponse(request, context, entry, now); asynchRevalidator.revalidateCacheEntry(this, route, request, context, execAware, entry); return resp; } return revalidateCacheEntry(route, request, context, execAware, entry); } catch (final IOException ioex) { return handleRevalidationFailure(request, context, entry, now); } } private CloseableHttpResponse handleCacheMiss( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware) throws IOException, HttpException { final HttpHost target = context.getTargetHost(); recordCacheMiss(target, request); if (!mayCallBackend(request)) { return Proxies.enhanceResponse( new BasicHttpResponse( HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout")); } final Map variants = getExistingCacheVariants(target, request); if (variants != null && variants.size() > 0) { return negotiateResponseFromVariants(route, request, context, execAware, variants); } return callBackend(route, request, context, execAware); } private HttpCacheEntry satisfyFromCache( final HttpHost target, final HttpRequestWrapper request) { HttpCacheEntry entry = null; try { entry = responseCache.getCacheEntry(target, request); } catch (final IOException ioe) { log.warn("Unable to retrieve entries from cache", ioe); } return entry; } private HttpResponse getFatallyNoncompliantResponse( final HttpRequestWrapper request, final HttpContext context) { HttpResponse fatalErrorResponse = null; final List fatalError = requestCompliance.requestIsFatallyNonCompliant(request); for (final RequestProtocolError error : fatalError) { setResponseStatus(context, CacheResponseStatus.CACHE_MODULE_RESPONSE); fatalErrorResponse = requestCompliance.getErrorForRequest(error); } return fatalErrorResponse; } private Map getExistingCacheVariants( final HttpHost target, final HttpRequestWrapper request) { Map variants = null; try { variants = responseCache.getVariantCacheEntriesWithEtags(target, request); } catch (final IOException ioe) { log.warn("Unable to retrieve variant entries from cache", ioe); } return variants; } private void recordCacheMiss(final HttpHost target, final HttpRequestWrapper request) { cacheMisses.getAndIncrement(); if (log.isTraceEnabled()) { final RequestLine rl = request.getRequestLine(); log.trace("Cache miss [host: " + target + "; uri: " + rl.getUri() + "]"); } } private void recordCacheHit(final HttpHost target, final HttpRequestWrapper request) { cacheHits.getAndIncrement(); if (log.isTraceEnabled()) { final RequestLine rl = request.getRequestLine(); log.trace("Cache hit [host: " + target + "; uri: " + rl.getUri() + "]"); } } private void recordCacheUpdate(final HttpContext context) { cacheUpdates.getAndIncrement(); setResponseStatus(context, CacheResponseStatus.VALIDATED); } private void flushEntriesInvalidatedByRequest( final HttpHost target, final HttpRequestWrapper request) { try { responseCache.flushInvalidatedCacheEntriesFor(target, request); } catch (final IOException ioe) { log.warn("Unable to flush invalidated entries from cache", ioe); } } private CloseableHttpResponse generateCachedResponse(final HttpRequestWrapper request, final HttpContext context, final HttpCacheEntry entry, final Date now) { final CloseableHttpResponse cachedResponse; if (request.containsHeader(HeaderConstants.IF_NONE_MATCH) || request.containsHeader(HeaderConstants.IF_MODIFIED_SINCE)) { cachedResponse = responseGenerator.generateNotModifiedResponse(entry); } else { cachedResponse = responseGenerator.generateResponse(entry); } setResponseStatus(context, CacheResponseStatus.CACHE_HIT); if (validityPolicy.getStalenessSecs(entry, now) > 0L) { cachedResponse.addHeader(HeaderConstants.WARNING,"110 localhost \"Response is stale\""); } return cachedResponse; } private CloseableHttpResponse handleRevalidationFailure( final HttpRequestWrapper request, final HttpContext context, final HttpCacheEntry entry, final Date now) { if (staleResponseNotAllowed(request, entry, now)) { return generateGatewayTimeout(context); } else { return unvalidatedCacheHit(context, entry); } } private CloseableHttpResponse generateGatewayTimeout( final HttpContext context) { setResponseStatus(context, CacheResponseStatus.CACHE_MODULE_RESPONSE); return Proxies.enhanceResponse(new BasicHttpResponse( HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout")); } private CloseableHttpResponse unvalidatedCacheHit( final HttpContext context, final HttpCacheEntry entry) { final CloseableHttpResponse cachedResponse = responseGenerator.generateResponse(entry); setResponseStatus(context, CacheResponseStatus.CACHE_HIT); cachedResponse.addHeader(HeaderConstants.WARNING, "111 localhost \"Revalidation failed\""); return cachedResponse; } private boolean staleResponseNotAllowed( final HttpRequestWrapper request, final HttpCacheEntry entry, final Date now) { return validityPolicy.mustRevalidate(entry) || (cacheConfig.isSharedCache() && validityPolicy.proxyRevalidate(entry)) || explicitFreshnessRequest(request, entry, now); } private boolean mayCallBackend(final HttpRequestWrapper request) { for (final Header h: request.getHeaders(HeaderConstants.CACHE_CONTROL)) { for (final HeaderElement elt : h.getElements()) { if ("only-if-cached".equals(elt.getName())) { log.trace("Request marked only-if-cached"); return false; } } } return true; } private boolean explicitFreshnessRequest( final HttpRequestWrapper request, final HttpCacheEntry entry, final Date now) { for(final Header h : request.getHeaders(HeaderConstants.CACHE_CONTROL)) { for(final HeaderElement elt : h.getElements()) { if (HeaderConstants.CACHE_CONTROL_MAX_STALE.equals(elt.getName())) { try { final int maxstale = Integer.parseInt(elt.getValue()); final long age = validityPolicy.getCurrentAgeSecs(entry, now); final long lifetime = validityPolicy.getFreshnessLifetimeSecs(entry); if (age - lifetime > maxstale) { return true; } } catch (final NumberFormatException nfe) { return true; } } else if (HeaderConstants.CACHE_CONTROL_MIN_FRESH.equals(elt.getName()) || HeaderConstants.CACHE_CONTROL_MAX_AGE.equals(elt.getName())) { return true; } } } return false; } private String generateViaHeader(final HttpMessage msg) { final ProtocolVersion pv = msg.getProtocolVersion(); final String existingEntry = viaHeaders.get(pv); if (existingEntry != null) { return existingEntry; } final VersionInfo vi = VersionInfo.loadVersionInfo("org.apache.http.client", getClass().getClassLoader()); final String release = (vi != null) ? vi.getRelease() : VersionInfo.UNAVAILABLE; String value; if ("http".equalsIgnoreCase(pv.getProtocol())) { value = String.format("%d.%d localhost (Apache-HttpClient/%s (cache))", pv.getMajor(), pv.getMinor(), release); } else { value = String.format("%s/%d.%d localhost (Apache-HttpClient/%s (cache))", pv.getProtocol(), pv.getMajor(), pv.getMinor(), release); } viaHeaders.put(pv, value); return value; } private void setResponseStatus(final HttpContext context, final CacheResponseStatus value) { if (context != null) { context.setAttribute(HttpCacheContext.CACHE_RESPONSE_STATUS, value); } } /** * Reports whether this {@code CachingHttpClient} implementation * supports byte-range requests as specified by the {@code Range} * and {@code Content-Range} headers. * @return {@code true} if byte-range requests are supported */ public boolean supportsRangeAndContentRangeHeaders() { return SUPPORTS_RANGE_AND_CONTENT_RANGE_HEADERS; } Date getCurrentDate() { return new Date(); } boolean clientRequestsOurOptions(final HttpRequest request) { final RequestLine line = request.getRequestLine(); if (!HeaderConstants.OPTIONS_METHOD.equals(line.getMethod())) { return false; } if (!"*".equals(line.getUri())) { return false; } if (!"0".equals(request.getFirstHeader(HeaderConstants.MAX_FORWARDS).getValue())) { return false; } return true; } CloseableHttpResponse callBackend( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware) throws IOException, HttpException { final Date requestDate = getCurrentDate(); log.trace("Calling the backend"); final CloseableHttpResponse backendResponse = backend.execute(route, request, context, execAware); try { backendResponse.addHeader("Via", generateViaHeader(backendResponse)); return handleBackendResponse(route, request, context, execAware, requestDate, getCurrentDate(), backendResponse); } catch (final IOException ex) { backendResponse.close(); throw ex; } catch (final RuntimeException ex) { backendResponse.close(); throw ex; } } private boolean revalidationResponseIsTooOld(final HttpResponse backendResponse, final HttpCacheEntry cacheEntry) { final Header entryDateHeader = cacheEntry.getFirstHeader(HTTP.DATE_HEADER); final Header responseDateHeader = backendResponse.getFirstHeader(HTTP.DATE_HEADER); if (entryDateHeader != null && responseDateHeader != null) { final Date entryDate = DateUtils.parseDate(entryDateHeader.getValue()); final Date respDate = DateUtils.parseDate(responseDateHeader.getValue()); if (entryDate == null || respDate == null) { // either backend response or cached entry did not have a valid // Date header, so we can't tell if they are out of order // according to the origin clock; thus we can skip the // unconditional retry recommended in 13.2.6 of RFC 2616. return false; } if (respDate.before(entryDate)) { return true; } } return false; } CloseableHttpResponse negotiateResponseFromVariants( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware, final Map variants) throws IOException, HttpException { final HttpRequestWrapper conditionalRequest = conditionalRequestBuilder .buildConditionalRequestFromVariants(request, variants); final Date requestDate = getCurrentDate(); final CloseableHttpResponse backendResponse = backend.execute( route, conditionalRequest, context, execAware); try { final Date responseDate = getCurrentDate(); backendResponse.addHeader("Via", generateViaHeader(backendResponse)); if (backendResponse.getStatusLine().getStatusCode() != HttpStatus.SC_NOT_MODIFIED) { return handleBackendResponse( route, request, context, execAware, requestDate, responseDate, backendResponse); } final Header resultEtagHeader = backendResponse.getFirstHeader(HeaderConstants.ETAG); if (resultEtagHeader == null) { log.warn("304 response did not contain ETag"); IOUtils.consume(backendResponse.getEntity()); backendResponse.close(); return callBackend(route, request, context, execAware); } final String resultEtag = resultEtagHeader.getValue(); final Variant matchingVariant = variants.get(resultEtag); if (matchingVariant == null) { log.debug("304 response did not contain ETag matching one sent in If-None-Match"); IOUtils.consume(backendResponse.getEntity()); backendResponse.close(); return callBackend(route, request, context, execAware); } final HttpCacheEntry matchedEntry = matchingVariant.getEntry(); if (revalidationResponseIsTooOld(backendResponse, matchedEntry)) { IOUtils.consume(backendResponse.getEntity()); backendResponse.close(); return retryRequestUnconditionally(route, request, context, execAware, matchedEntry); } recordCacheUpdate(context); final HttpCacheEntry responseEntry = getUpdatedVariantEntry( context.getTargetHost(), conditionalRequest, requestDate, responseDate, backendResponse, matchingVariant, matchedEntry); backendResponse.close(); final CloseableHttpResponse resp = responseGenerator.generateResponse(responseEntry); tryToUpdateVariantMap(context.getTargetHost(), request, matchingVariant); if (shouldSendNotModifiedResponse(request, responseEntry)) { return responseGenerator.generateNotModifiedResponse(responseEntry); } return resp; } catch (final IOException ex) { backendResponse.close(); throw ex; } catch (final RuntimeException ex) { backendResponse.close(); throw ex; } } private CloseableHttpResponse retryRequestUnconditionally( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware, final HttpCacheEntry matchedEntry) throws IOException, HttpException { final HttpRequestWrapper unconditional = conditionalRequestBuilder .buildUnconditionalRequest(request, matchedEntry); return callBackend(route, unconditional, context, execAware); } private HttpCacheEntry getUpdatedVariantEntry( final HttpHost target, final HttpRequestWrapper conditionalRequest, final Date requestDate, final Date responseDate, final CloseableHttpResponse backendResponse, final Variant matchingVariant, final HttpCacheEntry matchedEntry) throws IOException { HttpCacheEntry responseEntry = matchedEntry; try { responseEntry = responseCache.updateVariantCacheEntry(target, conditionalRequest, matchedEntry, backendResponse, requestDate, responseDate, matchingVariant.getCacheKey()); } catch (final IOException ioe) { log.warn("Could not update cache entry", ioe); } finally { backendResponse.close(); } return responseEntry; } private void tryToUpdateVariantMap( final HttpHost target, final HttpRequestWrapper request, final Variant matchingVariant) { try { responseCache.reuseVariantEntryFor(target, request, matchingVariant); } catch (final IOException ioe) { log.warn("Could not update cache entry to reuse variant", ioe); } } private boolean shouldSendNotModifiedResponse( final HttpRequestWrapper request, final HttpCacheEntry responseEntry) { return (suitabilityChecker.isConditional(request) && suitabilityChecker.allConditionalsMatch(request, responseEntry, new Date())); } CloseableHttpResponse revalidateCacheEntry( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware, final HttpCacheEntry cacheEntry) throws IOException, HttpException { final HttpRequestWrapper conditionalRequest = conditionalRequestBuilder.buildConditionalRequest(request, cacheEntry); Date requestDate = getCurrentDate(); CloseableHttpResponse backendResponse = backend.execute( route, conditionalRequest, context, execAware); Date responseDate = getCurrentDate(); if (revalidationResponseIsTooOld(backendResponse, cacheEntry)) { backendResponse.close(); final HttpRequestWrapper unconditional = conditionalRequestBuilder .buildUnconditionalRequest(request, cacheEntry); requestDate = getCurrentDate(); backendResponse = backend.execute(route, unconditional, context, execAware); responseDate = getCurrentDate(); } backendResponse.addHeader(HeaderConstants.VIA, generateViaHeader(backendResponse)); final int statusCode = backendResponse.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_NOT_MODIFIED || statusCode == HttpStatus.SC_OK) { recordCacheUpdate(context); } if (statusCode == HttpStatus.SC_NOT_MODIFIED) { final HttpCacheEntry updatedEntry = responseCache.updateCacheEntry( context.getTargetHost(), request, cacheEntry, backendResponse, requestDate, responseDate); if (suitabilityChecker.isConditional(request) && suitabilityChecker.allConditionalsMatch(request, updatedEntry, new Date())) { return responseGenerator .generateNotModifiedResponse(updatedEntry); } return responseGenerator.generateResponse(updatedEntry); } if (staleIfErrorAppliesTo(statusCode) && !staleResponseNotAllowed(request, cacheEntry, getCurrentDate()) && validityPolicy.mayReturnStaleIfError(request, cacheEntry, responseDate)) { try { final CloseableHttpResponse cachedResponse = responseGenerator.generateResponse(cacheEntry); cachedResponse.addHeader(HeaderConstants.WARNING, "110 localhost \"Response is stale\""); return cachedResponse; } finally { backendResponse.close(); } } return handleBackendResponse( route, conditionalRequest, context, execAware, requestDate, responseDate, backendResponse); } private boolean staleIfErrorAppliesTo(final int statusCode) { return statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR || statusCode == HttpStatus.SC_BAD_GATEWAY || statusCode == HttpStatus.SC_SERVICE_UNAVAILABLE || statusCode == HttpStatus.SC_GATEWAY_TIMEOUT; } CloseableHttpResponse handleBackendResponse( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware, final Date requestDate, final Date responseDate, final CloseableHttpResponse backendResponse) throws IOException { log.trace("Handling Backend response"); responseCompliance.ensureProtocolCompliance(request, backendResponse); final HttpHost target = context.getTargetHost(); final boolean cacheable = responseCachingPolicy.isResponseCacheable(request, backendResponse); responseCache.flushInvalidatedCacheEntriesFor(target, request, backendResponse); if (cacheable && !alreadyHaveNewerCacheEntry(target, request, backendResponse)) { storeRequestIfModifiedSinceFor304Response(request, backendResponse); return responseCache.cacheAndReturnResponse(target, request, backendResponse, requestDate, responseDate); } if (!cacheable) { try { responseCache.flushCacheEntriesFor(target, request); } catch (final IOException ioe) { log.warn("Unable to flush invalid cache entries", ioe); } } return backendResponse; } /** * For 304 Not modified responses, adds a "Last-Modified" header with the * value of the "If-Modified-Since" header passed in the request. This * header is required to be able to reuse match the cache entry for * subsequent requests but as defined in http specifications it is not * included in 304 responses by backend servers. This header will not be * included in the resulting response. */ private void storeRequestIfModifiedSinceFor304Response( final HttpRequest request, final HttpResponse backendResponse) { if (backendResponse.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_MODIFIED) { final Header h = request.getFirstHeader("If-Modified-Since"); if (h != null) { backendResponse.addHeader("Last-Modified", h.getValue()); } } } private boolean alreadyHaveNewerCacheEntry(final HttpHost target, final HttpRequestWrapper request, final HttpResponse backendResponse) { HttpCacheEntry existing = null; try { existing = responseCache.getCacheEntry(target, request); } catch (final IOException ioe) { // nop } if (existing == null) { return false; } final Header entryDateHeader = existing.getFirstHeader(HTTP.DATE_HEADER); if (entryDateHeader == null) { return false; } final Header responseDateHeader = backendResponse.getFirstHeader(HTTP.DATE_HEADER); if (responseDateHeader == null) { return false; } final Date entryDate = DateUtils.parseDate(entryDateHeader.getValue()); final Date responseDate = DateUtils.parseDate(responseDateHeader.getValue()); if (entryDate == null || responseDate == null) { return false; } return responseDate.before(entryDate); } } ././@LongLink0100644 0000000 0000000 00000000173 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClientBuilder.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Caching0100644 0000000 0000000 00000012651 12301751724 032223 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.File; import org.apache.http.client.cache.HttpCacheInvalidator; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.client.cache.ResourceFactory; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.execchain.ClientExecChain; /** * Builder for {@link org.apache.http.impl.client.CloseableHttpClient} * instances capable of client-side caching. * * @since 4.3 */ public class CachingHttpClientBuilder extends HttpClientBuilder { private ResourceFactory resourceFactory; private HttpCacheStorage storage; private File cacheDir; private CacheConfig cacheConfig; private SchedulingStrategy schedulingStrategy; private HttpCacheInvalidator httpCacheInvalidator; public static CachingHttpClientBuilder create() { return new CachingHttpClientBuilder(); } protected CachingHttpClientBuilder() { super(); } public final CachingHttpClientBuilder setResourceFactory( final ResourceFactory resourceFactory) { this.resourceFactory = resourceFactory; return this; } public final CachingHttpClientBuilder setHttpCacheStorage( final HttpCacheStorage storage) { this.storage = storage; return this; } public final CachingHttpClientBuilder setCacheDir( final File cacheDir) { this.cacheDir = cacheDir; return this; } public final CachingHttpClientBuilder setCacheConfig( final CacheConfig cacheConfig) { this.cacheConfig = cacheConfig; return this; } public final CachingHttpClientBuilder setSchedulingStrategy( final SchedulingStrategy schedulingStrategy) { this.schedulingStrategy = schedulingStrategy; return this; } public final CachingHttpClientBuilder setHttpCacheInvalidator( final HttpCacheInvalidator cacheInvalidator) { this.httpCacheInvalidator = cacheInvalidator; return this; } @Override protected ClientExecChain decorateMainExec(final ClientExecChain mainExec) { final CacheConfig config = this.cacheConfig != null ? this.cacheConfig : CacheConfig.DEFAULT; ResourceFactory resourceFactory = this.resourceFactory; if (resourceFactory == null) { if (this.cacheDir == null) { resourceFactory = new HeapResourceFactory(); } else { resourceFactory = new FileResourceFactory(cacheDir); } } HttpCacheStorage storage = this.storage; if (storage == null) { if (this.cacheDir == null) { storage = new BasicHttpCacheStorage(config); } else { final ManagedHttpCacheStorage managedStorage = new ManagedHttpCacheStorage(config); addCloseable(managedStorage); storage = managedStorage; } } final AsynchronousValidator revalidator = createAsynchronousRevalidator(config); final CacheKeyGenerator uriExtractor = new CacheKeyGenerator(); HttpCacheInvalidator cacheInvalidator = this.httpCacheInvalidator; if (cacheInvalidator == null) { cacheInvalidator = new CacheInvalidator(uriExtractor, storage); } return new CachingExec(mainExec, new BasicHttpCache( resourceFactory, storage, config, uriExtractor, cacheInvalidator), config, revalidator); } private AsynchronousValidator createAsynchronousRevalidator(final CacheConfig config) { if (config.getAsynchronousWorkersMax() > 0) { final SchedulingStrategy configuredSchedulingStrategy = createSchedulingStrategy(config); final AsynchronousValidator revalidator = new AsynchronousValidator( configuredSchedulingStrategy); addCloseable(revalidator); return revalidator; } return null; } @SuppressWarnings("resource") private SchedulingStrategy createSchedulingStrategy(final CacheConfig config) { return schedulingStrategy != null ? schedulingStrategy : new ImmediateSchedulingStrategy(config); } } ././@LongLink0100644 0000000 0000000 00000000165 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClients.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Caching0100644 0000000 0000000 00000004533 12301751724 032223 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.File; import org.apache.http.annotation.Immutable; import org.apache.http.impl.client.CloseableHttpClient; /** * Factory methods for {@link CloseableHttpClient} instances * capable of client-side caching. * * @since 4.3 */ @Immutable public class CachingHttpClients { private CachingHttpClients() { super(); } /** * Creates builder object for construction of custom * {@link CloseableHttpClient} instances. */ public static CachingHttpClientBuilder custom() { return CachingHttpClientBuilder.create(); } /** * Creates {@link CloseableHttpClient} instance that uses a memory bound * response cache. */ public static CloseableHttpClient createMemoryBound() { return CachingHttpClientBuilder.create().build(); } /** * Creates {@link CloseableHttpClient} instance that uses a file system * bound response cache. * * @param cacheDir location of response cache. */ public static CloseableHttpClient createFileBound(final File cacheDir) { return CachingHttpClientBuilder.create().setCacheDir(cacheDir).build(); } } ././@LongLink0100644 0000000 0000000 00000000161 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CombinedEntity.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Combine0100644 0000000 0000000 00000006125 12301751725 032243 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.SequenceInputStream; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.client.cache.Resource; import org.apache.http.entity.AbstractHttpEntity; import org.apache.http.util.Args; @NotThreadSafe class CombinedEntity extends AbstractHttpEntity { private final Resource resource; private final InputStream combinedStream; CombinedEntity(final Resource resource, final InputStream instream) throws IOException { super(); this.resource = resource; this.combinedStream = new SequenceInputStream( new ResourceStream(resource.getInputStream()), instream); } public long getContentLength() { return -1; } public boolean isRepeatable() { return false; } public boolean isStreaming() { return true; } public InputStream getContent() throws IOException, IllegalStateException { return this.combinedStream; } public void writeTo(final OutputStream outstream) throws IOException { Args.notNull(outstream, "Output stream"); final InputStream instream = getContent(); try { int l; final byte[] tmp = new byte[2048]; while ((l = instream.read(tmp)) != -1) { outstream.write(tmp, 0, l); } } finally { instream.close(); } } private void dispose() { this.resource.dispose(); } class ResourceStream extends FilterInputStream { protected ResourceStream(final InputStream in) { super(in); } @Override public void close() throws IOException { try { super.close(); } finally { dispose(); } } } } ././@LongLink0100644 0000000 0000000 00000000174 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ConditionalRequestBuilder.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Conditi0100644 0000000 0000000 00000014246 12301751720 032256 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.Map; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.ProtocolException; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.methods.HttpRequestWrapper; /** * @since 4.1 */ @Immutable class ConditionalRequestBuilder { /** * When a {@link HttpCacheEntry} is stale but 'might' be used as a response * to an {@link org.apache.http.HttpRequest} we will attempt to revalidate * the entry with the origin. Build the origin {@link org.apache.http.HttpRequest} * here and return it. * * @param request the original request from the caller * @param cacheEntry the entry that needs to be re-validated * @return the wrapped request * @throws ProtocolException when I am unable to build a new origin request. */ public HttpRequestWrapper buildConditionalRequest(final HttpRequestWrapper request, final HttpCacheEntry cacheEntry) throws ProtocolException { final HttpRequestWrapper newRequest = HttpRequestWrapper.wrap(request.getOriginal()); newRequest.setHeaders(request.getAllHeaders()); final Header eTag = cacheEntry.getFirstHeader(HeaderConstants.ETAG); if (eTag != null) { newRequest.setHeader(HeaderConstants.IF_NONE_MATCH, eTag.getValue()); } final Header lastModified = cacheEntry.getFirstHeader(HeaderConstants.LAST_MODIFIED); if (lastModified != null) { newRequest.setHeader(HeaderConstants.IF_MODIFIED_SINCE, lastModified.getValue()); } boolean mustRevalidate = false; for(final Header h : cacheEntry.getHeaders(HeaderConstants.CACHE_CONTROL)) { for(final HeaderElement elt : h.getElements()) { if (HeaderConstants.CACHE_CONTROL_MUST_REVALIDATE.equalsIgnoreCase(elt.getName()) || HeaderConstants.CACHE_CONTROL_PROXY_REVALIDATE.equalsIgnoreCase(elt.getName())) { mustRevalidate = true; break; } } } if (mustRevalidate) { newRequest.addHeader(HeaderConstants.CACHE_CONTROL, HeaderConstants.CACHE_CONTROL_MAX_AGE + "=0"); } return newRequest; } /** * When a {@link HttpCacheEntry} does not exist for a specific * {@link org.apache.http.HttpRequest} we attempt to see if an existing * {@link HttpCacheEntry} is appropriate by building a conditional * {@link org.apache.http.HttpRequest} using the variants' ETag values. * If no such values exist, the request is unmodified * * @param request the original request from the caller * @param variants * @return the wrapped request */ public HttpRequestWrapper buildConditionalRequestFromVariants(final HttpRequestWrapper request, final Map variants) { final HttpRequestWrapper newRequest = HttpRequestWrapper.wrap(request.getOriginal()); newRequest.setHeaders(request.getAllHeaders()); // we do not support partial content so all etags are used final StringBuilder etags = new StringBuilder(); boolean first = true; for(final String etag : variants.keySet()) { if (!first) { etags.append(","); } first = false; etags.append(etag); } newRequest.setHeader(HeaderConstants.IF_NONE_MATCH, etags.toString()); return newRequest; } /** * Returns a request to unconditionally validate a cache entry with * the origin. In certain cases (due to multiple intervening caches) * our cache may actually receive a response to a normal conditional * validation where the Date header is actually older than that of * our current cache entry. In this case, the protocol recommendation * is to retry the validation and force syncup with the origin. * @param request client request we are trying to satisfy * @param entry existing cache entry we are trying to validate * @return an unconditional validation request */ public HttpRequestWrapper buildUnconditionalRequest(final HttpRequestWrapper request, final HttpCacheEntry entry) { final HttpRequestWrapper newRequest = HttpRequestWrapper.wrap(request.getOriginal()); newRequest.setHeaders(request.getAllHeaders()); newRequest.addHeader(HeaderConstants.CACHE_CONTROL,HeaderConstants.CACHE_CONTROL_NO_CACHE); newRequest.addHeader(HeaderConstants.PRAGMA,HeaderConstants.CACHE_CONTROL_NO_CACHE); newRequest.removeHeaders(HeaderConstants.IF_RANGE); newRequest.removeHeaders(HeaderConstants.IF_MATCH); newRequest.removeHeaders(HeaderConstants.IF_NONE_MATCH); newRequest.removeHeaders(HeaderConstants.IF_UNMODIFIED_SINCE); newRequest.removeHeaders(HeaderConstants.IF_MODIFIED_SINCE); return newRequest; } } ././@LongLink0100644 0000000 0000000 00000000166 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/DefaultFailureCache.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Default0100644 0000000 0000000 00000012422 12301751725 032250 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.apache.http.annotation.ThreadSafe; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** * Implements a bounded failure cache. The oldest entries are discarded when * the maximum size is exceeded. * * @since 4.3 */ @ThreadSafe public class DefaultFailureCache implements FailureCache { static final int DEFAULT_MAX_SIZE = 1000; static final int MAX_UPDATE_TRIES = 10; private final int maxSize; private final ConcurrentMap storage; /** * Create a new failure cache with the maximum size of * {@link #DEFAULT_MAX_SIZE}. */ public DefaultFailureCache() { this(DEFAULT_MAX_SIZE); } /** * Creates a new failure cache with the specified maximum size. * @param maxSize the maximum number of entries the cache should store */ public DefaultFailureCache(final int maxSize) { this.maxSize = maxSize; this.storage = new ConcurrentHashMap(); } public int getErrorCount(final String identifier) { if (identifier == null) { throw new IllegalArgumentException("identifier may not be null"); } final FailureCacheValue storedErrorCode = storage.get(identifier); return storedErrorCode != null ? storedErrorCode.getErrorCount() : 0; } public void resetErrorCount(final String identifier) { if (identifier == null) { throw new IllegalArgumentException("identifier may not be null"); } storage.remove(identifier); } public void increaseErrorCount(final String identifier) { if (identifier == null) { throw new IllegalArgumentException("identifier may not be null"); } updateValue(identifier); removeOldestEntryIfMapSizeExceeded(); } private void updateValue(final String identifier) { /** * Due to concurrency it is possible that someone else is modifying an * entry before we could write back our updated value. So we keep * trying until it is our turn. * * In case there is a lot of contention on that identifier, a thread * might starve. Thus it gives up after a certain number of failed * update tries. */ for (int i = 0; i < MAX_UPDATE_TRIES; i++) { final FailureCacheValue oldValue = storage.get(identifier); if (oldValue == null) { final FailureCacheValue newValue = new FailureCacheValue(identifier, 1); if (storage.putIfAbsent(identifier, newValue) == null) { return; } } else { final int errorCount = oldValue.getErrorCount(); if (errorCount == Integer.MAX_VALUE) { return; } final FailureCacheValue newValue = new FailureCacheValue(identifier, errorCount + 1); if (storage.replace(identifier, oldValue, newValue)) { return; } } } } private void removeOldestEntryIfMapSizeExceeded() { if (storage.size() > maxSize) { final FailureCacheValue valueWithOldestTimestamp = findValueWithOldestTimestamp(); if (valueWithOldestTimestamp != null) { storage.remove(valueWithOldestTimestamp.getKey(), valueWithOldestTimestamp); } } } private FailureCacheValue findValueWithOldestTimestamp() { long oldestTimestamp = Long.MAX_VALUE; FailureCacheValue oldestValue = null; for (final Map.Entry storageEntry : storage.entrySet()) { final FailureCacheValue value = storageEntry.getValue(); final long creationTimeInNanos = value.getCreationTimeInNanos(); if (creationTimeInNanos < oldestTimestamp) { oldestTimestamp = creationTimeInNanos; oldestValue = storageEntry.getValue(); } } return oldestValue; } } ././@LongLink0100644 0000000 0000000 00000000202 12302131606 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/DefaultHttpCacheEntrySerializer.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Default0100644 0000000 0000000 00000005030 12301751724 032244 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheEntrySerializationException; import org.apache.http.client.cache.HttpCacheEntrySerializer; /** * {@link HttpCacheEntrySerializer} implementation that uses the default (native) * serialization. * * @see java.io.Serializable * * @since 4.1 */ @Immutable public class DefaultHttpCacheEntrySerializer implements HttpCacheEntrySerializer { public void writeTo(final HttpCacheEntry cacheEntry, final OutputStream os) throws IOException { final ObjectOutputStream oos = new ObjectOutputStream(os); try { oos.writeObject(cacheEntry); } finally { oos.close(); } } public HttpCacheEntry readFrom(final InputStream is) throws IOException { final ObjectInputStream ois = new ObjectInputStream(is); try { return (HttpCacheEntry) ois.readObject(); } catch (final ClassNotFoundException ex) { throw new HttpCacheEntrySerializationException("Class not found: " + ex.getMessage(), ex); } finally { ois.close(); } } } ././@LongLink0100644 0000000 0000000 00000000207 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ExponentialBackOffSchedulingStrategy.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Exponen0100644 0000000 0000000 00000016073 12301751722 032303 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.apache.http.annotation.ThreadSafe; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * An implementation that backs off exponentially based on the number of * consecutive failed attempts stored in the * {@link AsynchronousValidationRequest}. It uses the following defaults: *

 *         no delay in case it was never tried or didn't fail so far
 *     6 secs delay for one failed attempt (= {@link #getInitialExpiryInMillis()})
 *    60 secs delay for two failed attempts
 *    10 mins delay for three failed attempts
 *   100 mins delay for four failed attempts
 *  ~16 hours delay for five failed attempts
 *   24 hours delay for six or more failed attempts (= {@link #getMaxExpiryInMillis()})
 * 
* * The following equation is used to calculate the delay for a specific revalidation request: *
 *     delay = {@link #getInitialExpiryInMillis()} * Math.pow({@link #getBackOffRate()}, {@link AsynchronousValidationRequest#getConsecutiveFailedAttempts()} - 1))
 * 
* The resulting delay won't exceed {@link #getMaxExpiryInMillis()}. * * @since 4.3 */ @ThreadSafe public class ExponentialBackOffSchedulingStrategy implements SchedulingStrategy { public static final long DEFAULT_BACK_OFF_RATE = 10; public static final long DEFAULT_INITIAL_EXPIRY_IN_MILLIS = TimeUnit.SECONDS.toMillis(6); public static final long DEFAULT_MAX_EXPIRY_IN_MILLIS = TimeUnit.SECONDS.toMillis(86400); private final long backOffRate; private final long initialExpiryInMillis; private final long maxExpiryInMillis; private final ScheduledExecutorService executor; /** * Create a new scheduling strategy using a fixed pool of worker threads. * @param cacheConfig the thread pool configuration to be used; not null * @see org.apache.http.impl.client.cache.CacheConfig#getAsynchronousWorkersMax() * @see #DEFAULT_BACK_OFF_RATE * @see #DEFAULT_INITIAL_EXPIRY_IN_MILLIS * @see #DEFAULT_MAX_EXPIRY_IN_MILLIS */ public ExponentialBackOffSchedulingStrategy(final CacheConfig cacheConfig) { this(cacheConfig, DEFAULT_BACK_OFF_RATE, DEFAULT_INITIAL_EXPIRY_IN_MILLIS, DEFAULT_MAX_EXPIRY_IN_MILLIS); } /** * Create a new scheduling strategy by using a fixed pool of worker threads and the * given parameters to calculated the delay. * * @param cacheConfig the thread pool configuration to be used; not null * @param backOffRate the back off rate to be used; not negative * @param initialExpiryInMillis the initial expiry in milli seconds; not negative * @param maxExpiryInMillis the upper limit of the delay in milli seconds; not negative * @see org.apache.http.impl.client.cache.CacheConfig#getAsynchronousWorkersMax() * @see ExponentialBackOffSchedulingStrategy */ public ExponentialBackOffSchedulingStrategy( final CacheConfig cacheConfig, final long backOffRate, final long initialExpiryInMillis, final long maxExpiryInMillis) { this(createThreadPoolFromCacheConfig(cacheConfig), backOffRate, initialExpiryInMillis, maxExpiryInMillis); } private static ScheduledThreadPoolExecutor createThreadPoolFromCacheConfig( final CacheConfig cacheConfig) { final ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor( cacheConfig.getAsynchronousWorkersMax()); scheduledThreadPoolExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); return scheduledThreadPoolExecutor; } ExponentialBackOffSchedulingStrategy( final ScheduledExecutorService executor, final long backOffRate, final long initialExpiryInMillis, final long maxExpiryInMillis) { this.executor = checkNotNull("executor", executor); this.backOffRate = checkNotNegative("backOffRate", backOffRate); this.initialExpiryInMillis = checkNotNegative("initialExpiryInMillis", initialExpiryInMillis); this.maxExpiryInMillis = checkNotNegative("maxExpiryInMillis", maxExpiryInMillis); } public void schedule( final AsynchronousValidationRequest revalidationRequest) { checkNotNull("revalidationRequest", revalidationRequest); final int consecutiveFailedAttempts = revalidationRequest.getConsecutiveFailedAttempts(); final long delayInMillis = calculateDelayInMillis(consecutiveFailedAttempts); executor.schedule(revalidationRequest, delayInMillis, TimeUnit.MILLISECONDS); } public void close() { executor.shutdown(); } public long getBackOffRate() { return backOffRate; } public long getInitialExpiryInMillis() { return initialExpiryInMillis; } public long getMaxExpiryInMillis() { return maxExpiryInMillis; } protected long calculateDelayInMillis(final int consecutiveFailedAttempts) { if (consecutiveFailedAttempts > 0) { final long delayInSeconds = (long) (initialExpiryInMillis * Math.pow(backOffRate, consecutiveFailedAttempts - 1)); return Math.min(delayInSeconds, maxExpiryInMillis); } else { return 0; } } protected static T checkNotNull(final String parameterName, final T value) { if (value == null) { throw new IllegalArgumentException(parameterName + " may not be null"); } return value; } protected static long checkNotNegative(final String parameterName, final long value) { if (value < 0) { throw new IllegalArgumentException(parameterName + " may not be negative"); } return value; } } ././@LongLink0100644 0000000 0000000 00000000157 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/FailureCache.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Failure0100644 0000000 0000000 00000004004 12301751724 032247 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; /** * Increase and reset the number of errors associated with a specific * identifier. * * @since 4.3 */ public interface FailureCache { /** * Get the current error count. * @param identifier the identifier for which the error count is requested * @return the currently known error count or zero if there is no record */ int getErrorCount(String identifier); /** * Reset the error count back to zero. * @param identifier the identifier for which the error count should be * reset */ void resetErrorCount(String identifier); /** * Increases the error count by one. * @param identifier the identifier for which the error count should be * increased */ void increaseErrorCount(String identifier); } ././@LongLink0100644 0000000 0000000 00000000164 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/FailureCacheValue.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Failure0100644 0000000 0000000 00000004115 12301751724 032252 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.apache.http.annotation.Immutable; /** * The error count with a creation timestamp and its associated key. * * @since 4.3 */ @Immutable public class FailureCacheValue { private final long creationTimeInNanos; private final String key; private final int errorCount; public FailureCacheValue(final String key, final int errorCount) { this.creationTimeInNanos = System.nanoTime(); this.key = key; this.errorCount = errorCount; } public long getCreationTimeInNanos() { return creationTimeInNanos; } public String getKey() { return key; } public int getErrorCount() { return errorCount; } @Override public String toString() { return "[entry creationTimeInNanos=" + creationTimeInNanos + "; " + "key=" + key + "; errorCount=" + errorCount + ']'; } } ././@LongLink0100644 0000000 0000000 00000000157 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/FileResource.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/FileRes0100644 0000000 0000000 00000004327 12301751724 032221 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.cache.Resource; /** * Cache resource backed by a file. * * @since 4.1 */ @ThreadSafe public class FileResource implements Resource { private static final long serialVersionUID = 4132244415919043397L; private final File file; private volatile boolean disposed; public FileResource(final File file) { super(); this.file = file; this.disposed = false; } synchronized File getFile() { return this.file; } public synchronized InputStream getInputStream() throws IOException { return new FileInputStream(this.file); } public synchronized long length() { return this.file.length(); } public synchronized void dispose() { if (this.disposed) { return; } this.disposed = true; this.file.delete(); } } ././@LongLink0100644 0000000 0000000 00000000166 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/FileResourceFactory.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/FileRes0100644 0000000 0000000 00000007441 12301751724 032221 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.InputLimit; import org.apache.http.client.cache.Resource; import org.apache.http.client.cache.ResourceFactory; /** * Generates {@link Resource} instances whose body is stored in a temporary file. * * @since 4.1 */ @Immutable public class FileResourceFactory implements ResourceFactory { private final File cacheDir; private final BasicIdGenerator idgen; public FileResourceFactory(final File cacheDir) { super(); this.cacheDir = cacheDir; this.idgen = new BasicIdGenerator(); } private File generateUniqueCacheFile(final String requestId) { final StringBuilder buffer = new StringBuilder(); this.idgen.generate(buffer); buffer.append('.'); final int len = Math.min(requestId.length(), 100); for (int i = 0; i < len; i++) { final char ch = requestId.charAt(i); if (Character.isLetterOrDigit(ch) || ch == '.') { buffer.append(ch); } else { buffer.append('-'); } } return new File(this.cacheDir, buffer.toString()); } public Resource generate( final String requestId, final InputStream instream, final InputLimit limit) throws IOException { final File file = generateUniqueCacheFile(requestId); final FileOutputStream outstream = new FileOutputStream(file); try { final byte[] buf = new byte[2048]; long total = 0; int l; while ((l = instream.read(buf)) != -1) { outstream.write(buf, 0, l); total += l; if (limit != null && total > limit.getValue()) { limit.reached(); break; } } } finally { outstream.close(); } return new FileResource(file); } public Resource copy( final String requestId, final Resource resource) throws IOException { final File file = generateUniqueCacheFile(requestId); if (resource instanceof FileResource) { final File src = ((FileResource) resource).getFile(); IOUtils.copyFile(src, file); } else { final FileOutputStream out = new FileOutputStream(file); IOUtils.copyAndClose(resource.getInputStream(), out); } return new FileResource(file); } } ././@LongLink0100644 0000000 0000000 00000000157 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/HeapResource.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/HeapRes0100644 0000000 0000000 00000003662 12301751720 032214 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.ByteArrayInputStream; import java.io.InputStream; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.Resource; /** * Cache resource backed by a byte array on the heap. * * @since 4.1 */ @Immutable public class HeapResource implements Resource { private static final long serialVersionUID = -2078599905620463394L; private final byte[] b; public HeapResource(final byte[] b) { super(); this.b = b; } byte[] getByteArray() { return this.b; } public InputStream getInputStream() { return new ByteArrayInputStream(this.b); } public long length() { return this.b.length; } public void dispose() { } } ././@LongLink0100644 0000000 0000000 00000000166 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/HeapResourceFactory.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/HeapRes0100644 0000000 0000000 00000005564 12301751725 032224 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.InputLimit; import org.apache.http.client.cache.Resource; import org.apache.http.client.cache.ResourceFactory; /** * Generates {@link Resource} instances stored entirely in heap. * * @since 4.1 */ @Immutable public class HeapResourceFactory implements ResourceFactory { public Resource generate( final String requestId, final InputStream instream, final InputLimit limit) throws IOException { final ByteArrayOutputStream outstream = new ByteArrayOutputStream(); final byte[] buf = new byte[2048]; long total = 0; int l; while ((l = instream.read(buf)) != -1) { outstream.write(buf, 0, l); total += l; if (limit != null && total > limit.getValue()) { limit.reached(); break; } } return createResource(outstream.toByteArray()); } public Resource copy( final String requestId, final Resource resource) throws IOException { byte[] body; if (resource instanceof HeapResource) { body = ((HeapResource) resource).getByteArray(); } else { final ByteArrayOutputStream outstream = new ByteArrayOutputStream(); IOUtils.copyAndClose(resource.getInputStream(), outstream); body = outstream.toByteArray(); } return createResource(body); } Resource createResource(final byte[] buf) { return new HeapResource(buf); } } ././@LongLink0100644 0000000 0000000 00000000154 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/HttpCache.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/HttpCac0100644 0000000 0000000 00000013512 12301751724 032212 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import java.util.Date; import java.util.Map; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.methods.CloseableHttpResponse; /** * @since 4.1 */ interface HttpCache { /** * Clear all matching {@link HttpCacheEntry}s. * @param host * @param request * @throws IOException */ void flushCacheEntriesFor(HttpHost host, HttpRequest request) throws IOException; /** * Clear invalidated matching {@link HttpCacheEntry}s * @param host * @param request * @throws IOException */ void flushInvalidatedCacheEntriesFor(HttpHost host, HttpRequest request) throws IOException; /** Clear any entries that may be invalidated by the given response to * a particular request. * @param host * @param request * @param response */ void flushInvalidatedCacheEntriesFor(HttpHost host, HttpRequest request, HttpResponse response); /** * Retrieve matching {@link HttpCacheEntry} from the cache if it exists * @param host * @param request * @return the matching {@link HttpCacheEntry} or {@code null} * @throws IOException */ HttpCacheEntry getCacheEntry(HttpHost host, HttpRequest request) throws IOException; /** * Retrieve all variants from the cache, if there are no variants then an empty * {@link Map} is returned * @param host * @param request * @return a Map mapping Etags to variant cache entries * @throws IOException */ Map getVariantCacheEntriesWithEtags(HttpHost host, HttpRequest request) throws IOException; /** * Store a {@link HttpResponse} in the cache if possible, and return * @param host * @param request * @param originResponse * @param requestSent * @param responseReceived * @return the {@link HttpResponse} * @throws IOException */ HttpResponse cacheAndReturnResponse( HttpHost host, HttpRequest request, HttpResponse originResponse, Date requestSent, Date responseReceived) throws IOException; /** * Store a {@link HttpResponse} in the cache if possible, and return * @param host * @param request * @param originResponse * @param requestSent * @param responseReceived * @return the {@link HttpResponse} * @throws IOException */ CloseableHttpResponse cacheAndReturnResponse(HttpHost host, HttpRequest request, CloseableHttpResponse originResponse, Date requestSent, Date responseReceived) throws IOException; /** * Update a {@link HttpCacheEntry} using a 304 {@link HttpResponse}. * @param target * @param request * @param stale * @param originResponse * @param requestSent * @param responseReceived * @return the updated {@link HttpCacheEntry} * @throws IOException */ HttpCacheEntry updateCacheEntry( HttpHost target, HttpRequest request, HttpCacheEntry stale, HttpResponse originResponse, Date requestSent, Date responseReceived) throws IOException; /** * Update a specific {@link HttpCacheEntry} representing a cached variant * using a 304 {@link HttpResponse}. * @param target host for client request * @param request actual request from upstream client * @param stale current variant cache entry * @param originResponse 304 response received from origin * @param requestSent when the validating request was sent * @param responseReceived when the validating response was received * @param cacheKey where in the cache this entry is currently stored * @return the updated {@link HttpCacheEntry} * @throws IOException */ HttpCacheEntry updateVariantCacheEntry(HttpHost target, HttpRequest request, HttpCacheEntry stale, HttpResponse originResponse, Date requestSent, Date responseReceived, String cacheKey) throws IOException; /** * Specifies cache should reuse the given cached variant to satisfy * requests whose varying headers match those of the given client request. * @param target host of the upstream client request * @param req request sent by upstream client * @param variant variant cache entry to reuse * @throws IOException may be thrown during cache update */ void reuseVariantEntryFor(HttpHost target, final HttpRequest req, final Variant variant) throws IOException; } ././@LongLink0100644 0000000 0000000 00000000176 12302131606 011631 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ImmediateSchedulingStrategy.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Immedia0100644 0000000 0000000 00000006364 12301751724 032240 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.apache.http.annotation.ThreadSafe; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * Immediately schedules any incoming validation request. Relies on * {@link CacheConfig} to configure the used {@link java.util.concurrent.ThreadPoolExecutor}. * * @since 4.3 */ @ThreadSafe public class ImmediateSchedulingStrategy implements SchedulingStrategy { private final ExecutorService executor; /** * Uses a {@link java.util.concurrent.ThreadPoolExecutor} which is configured according to the * given {@link CacheConfig}. * @param cacheConfig specifies thread pool settings. See * {@link CacheConfig#getAsynchronousWorkersMax()}, * {@link CacheConfig#getAsynchronousWorkersCore()}, * {@link CacheConfig#getAsynchronousWorkerIdleLifetimeSecs()}, * and {@link CacheConfig#getRevalidationQueueSize()}. */ public ImmediateSchedulingStrategy(final CacheConfig cacheConfig) { this(new ThreadPoolExecutor( cacheConfig.getAsynchronousWorkersCore(), cacheConfig.getAsynchronousWorkersMax(), cacheConfig.getAsynchronousWorkerIdleLifetimeSecs(), TimeUnit.SECONDS, new ArrayBlockingQueue(cacheConfig.getRevalidationQueueSize())) ); } ImmediateSchedulingStrategy(final ExecutorService executor) { this.executor = executor; } public void schedule(final AsynchronousValidationRequest revalidationRequest) { if (revalidationRequest == null) { throw new IllegalArgumentException("AsynchronousValidationRequest may not be null"); } executor.execute(revalidationRequest); } public void close() { executor.shutdown(); } /** * Visible for testing. */ void awaitTermination(final long timeout, final TimeUnit unit) throws InterruptedException { executor.awaitTermination(timeout, unit); } } ././@LongLink0100644 0000000 0000000 00000000152 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/IOUtils.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/IOUtils0100644 0000000 0000000 00000006750 12301751724 032222 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import org.apache.http.HttpEntity; import org.apache.http.annotation.Immutable; @Immutable class IOUtils { static void consume(final HttpEntity entity) throws IOException { if (entity == null) { return; } if (entity.isStreaming()) { final InputStream instream = entity.getContent(); if (instream != null) { instream.close(); } } } static void copy(final InputStream in, final OutputStream out) throws IOException { final byte[] buf = new byte[2048]; int len; while ((len = in.read(buf)) != -1) { out.write(buf, 0, len); } } static void closeSilently(final Closeable closable) { try { closable.close(); } catch (final IOException ignore) { } } static void copyAndClose(final InputStream in, final OutputStream out) throws IOException { try { copy(in, out); in.close(); out.close(); } catch (final IOException ex) { closeSilently(in); closeSilently(out); // Propagate the original exception throw ex; } } static void copyFile(final File in, final File out) throws IOException { final RandomAccessFile f1 = new RandomAccessFile(in, "r"); final RandomAccessFile f2 = new RandomAccessFile(out, "rw"); try { final FileChannel c1 = f1.getChannel(); final FileChannel c2 = f2.getChannel(); try { c1.transferTo(0, f1.length(), c2); c1.close(); c2.close(); } catch (final IOException ex) { closeSilently(c1); closeSilently(c2); // Propagate the original exception throw ex; } f1.close(); f2.close(); } catch (final IOException ex) { closeSilently(f1); closeSilently(f2); // Propagate the original exception throw ex; } } } ././@LongLink0100644 0000000 0000000 00000000172 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ManagedHttpCacheStorage.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Managed0100644 0000000 0000000 00000013543 12301751724 032224 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.Closeable; import java.io.IOException; import java.lang.ref.ReferenceQueue; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.client.cache.HttpCacheUpdateCallback; import org.apache.http.client.cache.Resource; import org.apache.http.util.Args; /** * {@link HttpCacheStorage} implementation capable of deallocating resources associated with * the cache entries. This cache keeps track of cache entries using * {@link java.lang.ref.PhantomReference} and maintains a collection of all resources that * are no longer in use. The cache, however, does not automatically deallocates associated * resources by invoking {@link Resource#dispose()} method. The consumer MUST periodically * call {@link #cleanResources()} method to trigger resource deallocation. The cache can be * permanently shut down using {@link #shutdown()} method. All resources associated with * the entries used by the cache will be deallocated. * * This {@link HttpCacheStorage} implementation is intended for use with {@link FileResource} * and similar. * * @since 4.1 */ @ThreadSafe public class ManagedHttpCacheStorage implements HttpCacheStorage, Closeable { private final CacheMap entries; private final ReferenceQueue morque; private final Set resources; private final AtomicBoolean active; public ManagedHttpCacheStorage(final CacheConfig config) { super(); this.entries = new CacheMap(config.getMaxCacheEntries()); this.morque = new ReferenceQueue(); this.resources = new HashSet(); this.active = new AtomicBoolean(true); } private void ensureValidState() throws IllegalStateException { if (!this.active.get()) { throw new IllegalStateException("Cache has been shut down"); } } private void keepResourceReference(final HttpCacheEntry entry) { final Resource resource = entry.getResource(); if (resource != null) { // Must deallocate the resource when the entry is no longer in used final ResourceReference ref = new ResourceReference(entry, this.morque); this.resources.add(ref); } } public void putEntry(final String url, final HttpCacheEntry entry) throws IOException { Args.notNull(url, "URL"); Args.notNull(entry, "Cache entry"); ensureValidState(); synchronized (this) { this.entries.put(url, entry); keepResourceReference(entry); } } public HttpCacheEntry getEntry(final String url) throws IOException { Args.notNull(url, "URL"); ensureValidState(); synchronized (this) { return this.entries.get(url); } } public void removeEntry(final String url) throws IOException { Args.notNull(url, "URL"); ensureValidState(); synchronized (this) { // Cannot deallocate the associated resources immediately as the // cache entry may still be in use this.entries.remove(url); } } public void updateEntry( final String url, final HttpCacheUpdateCallback callback) throws IOException { Args.notNull(url, "URL"); Args.notNull(callback, "Callback"); ensureValidState(); synchronized (this) { final HttpCacheEntry existing = this.entries.get(url); final HttpCacheEntry updated = callback.update(existing); this.entries.put(url, updated); if (existing != updated) { keepResourceReference(updated); } } } public void cleanResources() { if (this.active.get()) { ResourceReference ref; while ((ref = (ResourceReference) this.morque.poll()) != null) { synchronized (this) { this.resources.remove(ref); } ref.getResource().dispose(); } } } public void shutdown() { if (this.active.compareAndSet(true, false)) { synchronized (this) { this.entries.clear(); for (final ResourceReference ref: this.resources) { ref.getResource().dispose(); } this.resources.clear(); while (this.morque.poll() != null) { } } } } public void close() { shutdown(); } } ././@LongLink0100644 0000000 0000000 00000000170 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/OptionsHttp11Response.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Options0100644 0000000 0000000 00000013133 12301751725 032317 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.Locale; import org.apache.http.Header; import org.apache.http.HeaderIterator; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.ProtocolVersion; import org.apache.http.StatusLine; import org.apache.http.annotation.Immutable; import org.apache.http.message.AbstractHttpMessage; import org.apache.http.message.BasicStatusLine; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpParams; /** * @since 4.1 */ @SuppressWarnings("deprecation") @Immutable final class OptionsHttp11Response extends AbstractHttpMessage implements HttpResponse { private final StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_IMPLEMENTED, ""); private final ProtocolVersion version = HttpVersion.HTTP_1_1; public StatusLine getStatusLine() { return statusLine; } public void setStatusLine(final StatusLine statusline) { // No-op on purpose, this class is not going to be doing any work. } public void setStatusLine(final ProtocolVersion ver, final int code) { // No-op on purpose, this class is not going to be doing any work. } public void setStatusLine(final ProtocolVersion ver, final int code, final String reason) { // No-op on purpose, this class is not going to be doing any work. } public void setStatusCode(final int code) throws IllegalStateException { // No-op on purpose, this class is not going to be doing any work. } public void setReasonPhrase(final String reason) throws IllegalStateException { // No-op on purpose, this class is not going to be doing any work. } public HttpEntity getEntity() { return null; } public void setEntity(final HttpEntity entity) { // No-op on purpose, this class is not going to be doing any work. } public Locale getLocale() { return null; } public void setLocale(final Locale loc) { // No-op on purpose, this class is not going to be doing any work. } public ProtocolVersion getProtocolVersion() { return version; } @Override public boolean containsHeader(final String name) { return this.headergroup.containsHeader(name); } @Override public Header[] getHeaders(final String name) { return this.headergroup.getHeaders(name); } @Override public Header getFirstHeader(final String name) { return this.headergroup.getFirstHeader(name); } @Override public Header getLastHeader(final String name) { return this.headergroup.getLastHeader(name); } @Override public Header[] getAllHeaders() { return this.headergroup.getAllHeaders(); } @Override public void addHeader(final Header header) { // No-op on purpose, this class is not going to be doing any work. } @Override public void addHeader(final String name, final String value) { // No-op on purpose, this class is not going to be doing any work. } @Override public void setHeader(final Header header) { // No-op on purpose, this class is not going to be doing any work. } @Override public void setHeader(final String name, final String value) { // No-op on purpose, this class is not going to be doing any work. } @Override public void setHeaders(final Header[] headers) { // No-op on purpose, this class is not going to be doing any work. } @Override public void removeHeader(final Header header) { // No-op on purpose, this class is not going to be doing any work. } @Override public void removeHeaders(final String name) { // No-op on purpose, this class is not going to be doing any work. } @Override public HeaderIterator headerIterator() { return this.headergroup.iterator(); } @Override public HeaderIterator headerIterator(final String name) { return this.headergroup.iterator(name); } @Override public HttpParams getParams() { if (this.params == null) { this.params = new BasicHttpParams(); } return this.params; } @Override public void setParams(final HttpParams params) { // No-op on purpose, this class is not going to be doing any work. } } ././@LongLink0100644 0000000 0000000 00000000152 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/package.htmlhttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/package0100644 0000000 0000000 00000003164 12301751724 032261 0ustar000000000 0000000

This package contains a cache module that can be used for HTTP/1.1 client-side caching. The primary classes in this package are the {@link org.apache.http.impl.client.cache.CachingHttpClient}, which is a drop-in replacement for a {@link org.apache.http.impl.client.DefaultHttpClient} that adds caching, and the {@link org.apache.http.impl.client.cache.CacheConfig} class that can be used for configuring it.

././@LongLink0100644 0000000 0000000 00000000152 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Proxies.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Proxies0100644 0000000 0000000 00000004034 12301751722 032312 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.lang.reflect.Proxy; import org.apache.http.HttpResponse; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.util.Args; /** * Proxies for HTTP message objects. * * @since 4.3 */ @NotThreadSafe class Proxies { public static CloseableHttpResponse enhanceResponse(final HttpResponse original) { Args.notNull(original, "HTTP response"); if (original instanceof CloseableHttpResponse) { return (CloseableHttpResponse) original; } else { return (CloseableHttpResponse) Proxy.newProxyInstance( ResponseProxyHandler.class.getClassLoader(), new Class[] { CloseableHttpResponse.class }, new ResponseProxyHandler(original)); } } } ././@LongLink0100644 0000000 0000000 00000000174 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/RequestProtocolCompliance.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Request0100644 0000000 0000000 00000034035 12301751724 032317 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.ProtocolVersion; import org.apache.http.annotation.Immutable; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.entity.AbstractHttpEntity; import org.apache.http.entity.ContentType; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpResponse; import org.apache.http.message.BasicStatusLine; import org.apache.http.protocol.HTTP; /** * @since 4.1 */ @Immutable class RequestProtocolCompliance { private final boolean weakETagOnPutDeleteAllowed; public RequestProtocolCompliance() { super(); this.weakETagOnPutDeleteAllowed = false; } public RequestProtocolCompliance(final boolean weakETagOnPutDeleteAllowed) { super(); this.weakETagOnPutDeleteAllowed = weakETagOnPutDeleteAllowed; } private static final List disallowedWithNoCache = Arrays.asList(HeaderConstants.CACHE_CONTROL_MIN_FRESH, HeaderConstants.CACHE_CONTROL_MAX_STALE, HeaderConstants.CACHE_CONTROL_MAX_AGE); /** * Test to see if the {@link HttpRequest} is HTTP1.1 compliant or not * and if not, we can not continue. * * @param request the HttpRequest Object * @return list of {@link RequestProtocolError} */ public List requestIsFatallyNonCompliant(final HttpRequest request) { final List theErrors = new ArrayList(); RequestProtocolError anError = requestHasWeakETagAndRange(request); if (anError != null) { theErrors.add(anError); } if (!weakETagOnPutDeleteAllowed) { anError = requestHasWeekETagForPUTOrDELETEIfMatch(request); if (anError != null) { theErrors.add(anError); } } anError = requestContainsNoCacheDirectiveWithFieldName(request); if (anError != null) { theErrors.add(anError); } return theErrors; } /** * If the {@link HttpRequest} is non-compliant but 'fixable' we go ahead and * fix the request here. * * @param request the request to check for compliance * @throws ClientProtocolException when we have trouble making the request compliant */ public void makeRequestCompliant(final HttpRequestWrapper request) throws ClientProtocolException { if (requestMustNotHaveEntity(request)) { ((HttpEntityEnclosingRequest) request).setEntity(null); } verifyRequestWithExpectContinueFlagHas100continueHeader(request); verifyOPTIONSRequestWithBodyHasContentType(request); decrementOPTIONSMaxForwardsIfGreaterThen0(request); stripOtherFreshnessDirectivesWithNoCache(request); if (requestVersionIsTooLow(request) || requestMinorVersionIsTooHighMajorVersionsMatch(request)) { request.setProtocolVersion(HttpVersion.HTTP_1_1); } } private void stripOtherFreshnessDirectivesWithNoCache(final HttpRequest request) { final List outElts = new ArrayList(); boolean shouldStrip = false; for(final Header h : request.getHeaders(HeaderConstants.CACHE_CONTROL)) { for(final HeaderElement elt : h.getElements()) { if (!disallowedWithNoCache.contains(elt.getName())) { outElts.add(elt); } if (HeaderConstants.CACHE_CONTROL_NO_CACHE.equals(elt.getName())) { shouldStrip = true; } } } if (!shouldStrip) { return; } request.removeHeaders(HeaderConstants.CACHE_CONTROL); request.setHeader(HeaderConstants.CACHE_CONTROL, buildHeaderFromElements(outElts)); } private String buildHeaderFromElements(final List outElts) { final StringBuilder newHdr = new StringBuilder(""); boolean first = true; for(final HeaderElement elt : outElts) { if (!first) { newHdr.append(","); } else { first = false; } newHdr.append(elt.toString()); } return newHdr.toString(); } private boolean requestMustNotHaveEntity(final HttpRequest request) { return HeaderConstants.TRACE_METHOD.equals(request.getRequestLine().getMethod()) && request instanceof HttpEntityEnclosingRequest; } private void decrementOPTIONSMaxForwardsIfGreaterThen0(final HttpRequest request) { if (!HeaderConstants.OPTIONS_METHOD.equals(request.getRequestLine().getMethod())) { return; } final Header maxForwards = request.getFirstHeader(HeaderConstants.MAX_FORWARDS); if (maxForwards == null) { return; } request.removeHeaders(HeaderConstants.MAX_FORWARDS); final int currentMaxForwards = Integer.parseInt(maxForwards.getValue()); request.setHeader(HeaderConstants.MAX_FORWARDS, Integer.toString(currentMaxForwards - 1)); } private void verifyOPTIONSRequestWithBodyHasContentType(final HttpRequest request) { if (!HeaderConstants.OPTIONS_METHOD.equals(request.getRequestLine().getMethod())) { return; } if (!(request instanceof HttpEntityEnclosingRequest)) { return; } addContentTypeHeaderIfMissing((HttpEntityEnclosingRequest) request); } private void addContentTypeHeaderIfMissing(final HttpEntityEnclosingRequest request) { if (request.getEntity().getContentType() == null) { ((AbstractHttpEntity) request.getEntity()).setContentType( ContentType.APPLICATION_OCTET_STREAM.getMimeType()); } } private void verifyRequestWithExpectContinueFlagHas100continueHeader(final HttpRequest request) { if (request instanceof HttpEntityEnclosingRequest) { if (((HttpEntityEnclosingRequest) request).expectContinue() && ((HttpEntityEnclosingRequest) request).getEntity() != null) { add100ContinueHeaderIfMissing(request); } else { remove100ContinueHeaderIfExists(request); } } else { remove100ContinueHeaderIfExists(request); } } private void remove100ContinueHeaderIfExists(final HttpRequest request) { boolean hasHeader = false; final Header[] expectHeaders = request.getHeaders(HTTP.EXPECT_DIRECTIVE); List expectElementsThatAreNot100Continue = new ArrayList(); for (final Header h : expectHeaders) { for (final HeaderElement elt : h.getElements()) { if (!(HTTP.EXPECT_CONTINUE.equalsIgnoreCase(elt.getName()))) { expectElementsThatAreNot100Continue.add(elt); } else { hasHeader = true; } } if (hasHeader) { request.removeHeader(h); for (final HeaderElement elt : expectElementsThatAreNot100Continue) { final BasicHeader newHeader = new BasicHeader(HTTP.EXPECT_DIRECTIVE, elt.getName()); request.addHeader(newHeader); } return; } else { expectElementsThatAreNot100Continue = new ArrayList(); } } } private void add100ContinueHeaderIfMissing(final HttpRequest request) { boolean hasHeader = false; for (final Header h : request.getHeaders(HTTP.EXPECT_DIRECTIVE)) { for (final HeaderElement elt : h.getElements()) { if (HTTP.EXPECT_CONTINUE.equalsIgnoreCase(elt.getName())) { hasHeader = true; } } } if (!hasHeader) { request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE); } } protected boolean requestMinorVersionIsTooHighMajorVersionsMatch(final HttpRequest request) { final ProtocolVersion requestProtocol = request.getProtocolVersion(); if (requestProtocol.getMajor() != HttpVersion.HTTP_1_1.getMajor()) { return false; } if (requestProtocol.getMinor() > HttpVersion.HTTP_1_1.getMinor()) { return true; } return false; } protected boolean requestVersionIsTooLow(final HttpRequest request) { return request.getProtocolVersion().compareToVersion(HttpVersion.HTTP_1_1) < 0; } /** * Extract error information about the {@link HttpRequest} telling the 'caller' * that a problem occured. * * @param errorCheck What type of error should I get * @return The {@link HttpResponse} that is the error generated */ public HttpResponse getErrorForRequest(final RequestProtocolError errorCheck) { switch (errorCheck) { case BODY_BUT_NO_LENGTH_ERROR: return new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_LENGTH_REQUIRED, "")); case WEAK_ETAG_AND_RANGE_ERROR: return new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_BAD_REQUEST, "Weak eTag not compatible with byte range")); case WEAK_ETAG_ON_PUTDELETE_METHOD_ERROR: return new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_BAD_REQUEST, "Weak eTag not compatible with PUT or DELETE requests")); case NO_CACHE_DIRECTIVE_WITH_FIELD_NAME: return new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_BAD_REQUEST, "No-Cache directive MUST NOT include a field name")); default: throw new IllegalStateException( "The request was compliant, therefore no error can be generated for it."); } } private RequestProtocolError requestHasWeakETagAndRange(final HttpRequest request) { // TODO: Should these be looking at all the headers marked as Range? final String method = request.getRequestLine().getMethod(); if (!(HeaderConstants.GET_METHOD.equals(method))) { return null; } final Header range = request.getFirstHeader(HeaderConstants.RANGE); if (range == null) { return null; } final Header ifRange = request.getFirstHeader(HeaderConstants.IF_RANGE); if (ifRange == null) { return null; } final String val = ifRange.getValue(); if (val.startsWith("W/")) { return RequestProtocolError.WEAK_ETAG_AND_RANGE_ERROR; } return null; } private RequestProtocolError requestHasWeekETagForPUTOrDELETEIfMatch(final HttpRequest request) { // TODO: Should these be looking at all the headers marked as If-Match/If-None-Match? final String method = request.getRequestLine().getMethod(); if (!(HeaderConstants.PUT_METHOD.equals(method) || HeaderConstants.DELETE_METHOD .equals(method))) { return null; } final Header ifMatch = request.getFirstHeader(HeaderConstants.IF_MATCH); if (ifMatch != null) { final String val = ifMatch.getValue(); if (val.startsWith("W/")) { return RequestProtocolError.WEAK_ETAG_ON_PUTDELETE_METHOD_ERROR; } } else { final Header ifNoneMatch = request.getFirstHeader(HeaderConstants.IF_NONE_MATCH); if (ifNoneMatch == null) { return null; } final String val2 = ifNoneMatch.getValue(); if (val2.startsWith("W/")) { return RequestProtocolError.WEAK_ETAG_ON_PUTDELETE_METHOD_ERROR; } } return null; } private RequestProtocolError requestContainsNoCacheDirectiveWithFieldName(final HttpRequest request) { for(final Header h : request.getHeaders(HeaderConstants.CACHE_CONTROL)) { for(final HeaderElement elt : h.getElements()) { if (HeaderConstants.CACHE_CONTROL_NO_CACHE.equalsIgnoreCase(elt.getName()) && elt.getValue() != null) { return RequestProtocolError.NO_CACHE_DIRECTIVE_WITH_FIELD_NAME; } } } return null; } } ././@LongLink0100644 0000000 0000000 00000000167 12302131606 011631 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/RequestProtocolError.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Request0100644 0000000 0000000 00000002634 12301751724 032317 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; /** * @since 4.1 */ enum RequestProtocolError { UNKNOWN, BODY_BUT_NO_LENGTH_ERROR, WEAK_ETAG_ON_PUTDELETE_METHOD_ERROR, WEAK_ETAG_AND_RANGE_ERROR, NO_CACHE_DIRECTIVE_WITH_FIELD_NAME } ././@LongLink0100644 0000000 0000000 00000000164 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ResourceReference.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Resourc0100644 0000000 0000000 00000004071 12301751724 032306 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.Resource; import org.apache.http.util.Args; @Immutable class ResourceReference extends PhantomReference { private final Resource resource; public ResourceReference(final HttpCacheEntry entry, final ReferenceQueue q) { super(entry, q); Args.notNull(entry.getResource(), "Resource"); this.resource = entry.getResource(); } public Resource getResource() { return this.resource; } @Override public int hashCode() { return this.resource.hashCode(); } @Override public boolean equals(final Object obj) { return this.resource.equals(obj); } } ././@LongLink0100644 0000000 0000000 00000000170 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ResponseCachingPolicy.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Respons0100644 0000000 0000000 00000027373 12301751724 032327 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.Arrays; import java.util.Date; import java.util.HashSet; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpMessage; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.annotation.Immutable; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.utils.DateUtils; import org.apache.http.protocol.HTTP; /** * Determines if an HttpResponse can be cached. * * @since 4.1 */ @Immutable class ResponseCachingPolicy { private static final String[] AUTH_CACHEABLE_PARAMS = { "s-maxage", HeaderConstants.CACHE_CONTROL_MUST_REVALIDATE, HeaderConstants.PUBLIC }; private final long maxObjectSizeBytes; private final boolean sharedCache; private final boolean neverCache1_0ResponsesWithQueryString; private final Log log = LogFactory.getLog(getClass()); private static final Set cacheableStatuses = new HashSet(Arrays.asList(HttpStatus.SC_OK, HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION, HttpStatus.SC_MULTIPLE_CHOICES, HttpStatus.SC_MOVED_PERMANENTLY, HttpStatus.SC_GONE)); private final Set uncacheableStatuses; /** * Define a cache policy that limits the size of things that should be stored * in the cache to a maximum of {@link HttpResponse} bytes in size. * * @param maxObjectSizeBytes the size to limit items into the cache * @param sharedCache whether to behave as a shared cache (true) or a * non-shared/private cache (false) * @param neverCache1_0ResponsesWithQueryString true to never cache HTTP 1.0 responses with a query string, false * to cache if explicit cache headers are found. * @param allow303Caching if this policy is permitted to cache 303 response */ public ResponseCachingPolicy(final long maxObjectSizeBytes, final boolean sharedCache, final boolean neverCache1_0ResponsesWithQueryString, final boolean allow303Caching) { this.maxObjectSizeBytes = maxObjectSizeBytes; this.sharedCache = sharedCache; this.neverCache1_0ResponsesWithQueryString = neverCache1_0ResponsesWithQueryString; if (allow303Caching) { uncacheableStatuses = new HashSet( Arrays.asList(HttpStatus.SC_PARTIAL_CONTENT)); } else { uncacheableStatuses = new HashSet(Arrays.asList( HttpStatus.SC_PARTIAL_CONTENT, HttpStatus.SC_SEE_OTHER)); } } /** * Determines if an HttpResponse can be cached. * * @param httpMethod What type of request was this, a GET, PUT, other? * @param response The origin response * @return true if response is cacheable */ public boolean isResponseCacheable(final String httpMethod, final HttpResponse response) { boolean cacheable = false; if (!HeaderConstants.GET_METHOD.equals(httpMethod)) { log.debug("Response was not cacheable."); return false; } final int status = response.getStatusLine().getStatusCode(); if (cacheableStatuses.contains(status)) { // these response codes MAY be cached cacheable = true; } else if (uncacheableStatuses.contains(status)) { return false; } else if (unknownStatusCode(status)) { // a response with an unknown status code MUST NOT be // cached return false; } final Header contentLength = response.getFirstHeader(HTTP.CONTENT_LEN); if (contentLength != null) { final int contentLengthValue = Integer.parseInt(contentLength.getValue()); if (contentLengthValue > this.maxObjectSizeBytes) { return false; } } final Header[] ageHeaders = response.getHeaders(HeaderConstants.AGE); if (ageHeaders.length > 1) { return false; } final Header[] expiresHeaders = response.getHeaders(HeaderConstants.EXPIRES); if (expiresHeaders.length > 1) { return false; } final Header[] dateHeaders = response.getHeaders(HTTP.DATE_HEADER); if (dateHeaders.length != 1) { return false; } final Date date = DateUtils.parseDate(dateHeaders[0].getValue()); if (date == null) { return false; } for (final Header varyHdr : response.getHeaders(HeaderConstants.VARY)) { for (final HeaderElement elem : varyHdr.getElements()) { if ("*".equals(elem.getName())) { return false; } } } if (isExplicitlyNonCacheable(response)) { return false; } return (cacheable || isExplicitlyCacheable(response)); } private boolean unknownStatusCode(final int status) { if (status >= 100 && status <= 101) { return false; } if (status >= 200 && status <= 206) { return false; } if (status >= 300 && status <= 307) { return false; } if (status >= 400 && status <= 417) { return false; } if (status >= 500 && status <= 505) { return false; } return true; } protected boolean isExplicitlyNonCacheable(final HttpResponse response) { final Header[] cacheControlHeaders = response.getHeaders(HeaderConstants.CACHE_CONTROL); for (final Header header : cacheControlHeaders) { for (final HeaderElement elem : header.getElements()) { if (HeaderConstants.CACHE_CONTROL_NO_STORE.equals(elem.getName()) || HeaderConstants.CACHE_CONTROL_NO_CACHE.equals(elem.getName()) || (sharedCache && HeaderConstants.PRIVATE.equals(elem.getName()))) { return true; } } } return false; } protected boolean hasCacheControlParameterFrom(final HttpMessage msg, final String[] params) { final Header[] cacheControlHeaders = msg.getHeaders(HeaderConstants.CACHE_CONTROL); for (final Header header : cacheControlHeaders) { for (final HeaderElement elem : header.getElements()) { for (final String param : params) { if (param.equalsIgnoreCase(elem.getName())) { return true; } } } } return false; } protected boolean isExplicitlyCacheable(final HttpResponse response) { if (response.getFirstHeader(HeaderConstants.EXPIRES) != null) { return true; } final String[] cacheableParams = { HeaderConstants.CACHE_CONTROL_MAX_AGE, "s-maxage", HeaderConstants.CACHE_CONTROL_MUST_REVALIDATE, HeaderConstants.CACHE_CONTROL_PROXY_REVALIDATE, HeaderConstants.PUBLIC }; return hasCacheControlParameterFrom(response, cacheableParams); } /** * Determine if the {@link HttpResponse} gotten from the origin is a * cacheable response. * * @param request the {@link HttpRequest} that generated an origin hit * @param response the {@link HttpResponse} from the origin * @return true if response is cacheable */ public boolean isResponseCacheable(final HttpRequest request, final HttpResponse response) { if (requestProtocolGreaterThanAccepted(request)) { log.debug("Response was not cacheable."); return false; } final String[] uncacheableRequestDirectives = { HeaderConstants.CACHE_CONTROL_NO_STORE }; if (hasCacheControlParameterFrom(request,uncacheableRequestDirectives)) { return false; } if (request.getRequestLine().getUri().contains("?")) { if (neverCache1_0ResponsesWithQueryString && from1_0Origin(response)) { log.debug("Response was not cacheable as it had a query string."); return false; } else if (!isExplicitlyCacheable(response)) { log.debug("Response was not cacheable as it is missing explicit caching headers."); return false; } } if (expiresHeaderLessOrEqualToDateHeaderAndNoCacheControl(response)) { return false; } if (sharedCache) { final Header[] authNHeaders = request.getHeaders(HeaderConstants.AUTHORIZATION); if (authNHeaders != null && authNHeaders.length > 0 && !hasCacheControlParameterFrom(response, AUTH_CACHEABLE_PARAMS)) { return false; } } final String method = request.getRequestLine().getMethod(); return isResponseCacheable(method, response); } private boolean expiresHeaderLessOrEqualToDateHeaderAndNoCacheControl( final HttpResponse response) { if (response.getFirstHeader(HeaderConstants.CACHE_CONTROL) != null) { return false; } final Header expiresHdr = response.getFirstHeader(HeaderConstants.EXPIRES); final Header dateHdr = response.getFirstHeader(HTTP.DATE_HEADER); if (expiresHdr == null || dateHdr == null) { return false; } final Date expires = DateUtils.parseDate(expiresHdr.getValue()); final Date date = DateUtils.parseDate(dateHdr.getValue()); if (expires == null || date == null) { return false; } return expires.equals(date) || expires.before(date); } private boolean from1_0Origin(final HttpResponse response) { final Header via = response.getFirstHeader(HeaderConstants.VIA); if (via != null) { for(final HeaderElement elt : via.getElements()) { final String proto = elt.toString().split("\\s")[0]; if (proto.contains("/")) { return proto.equals("HTTP/1.0"); } else { return proto.equals("1.0"); } } } return HttpVersion.HTTP_1_0.equals(response.getProtocolVersion()); } private boolean requestProtocolGreaterThanAccepted(final HttpRequest req) { return req.getProtocolVersion().compareToVersion(HttpVersion.HTTP_1_1) > 0; } } ././@LongLink0100644 0000000 0000000 00000000175 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ResponseProtocolCompliance.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Respons0100644 0000000 0000000 00000023176 12301751724 032324 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.annotation.Immutable; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.utils.DateUtils; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.HTTP; /** * @since 4.1 */ @Immutable class ResponseProtocolCompliance { private static final String UNEXPECTED_100_CONTINUE = "The incoming request did not contain a " + "100-continue header, but the response was a Status 100, continue."; private static final String UNEXPECTED_PARTIAL_CONTENT = "partial content was returned for a request that did not ask for it"; /** * When we get a response from a down stream server (Origin Server) * we attempt to see if it is HTTP 1.1 Compliant and if not, attempt to * make it so. * * @param request The {@link HttpRequest} that generated an origin hit and response * @param response The {@link HttpResponse} from the origin server * @throws IOException Bad things happened */ public void ensureProtocolCompliance(final HttpRequestWrapper request, final HttpResponse response) throws IOException { if (backendResponseMustNotHaveBody(request, response)) { consumeBody(response); response.setEntity(null); } requestDidNotExpect100ContinueButResponseIsOne(request, response); transferEncodingIsNotReturnedTo1_0Client(request, response); ensurePartialContentIsNotSentToAClientThatDidNotRequestIt(request, response); ensure200ForOPTIONSRequestWithNoBodyHasContentLengthZero(request, response); ensure206ContainsDateHeader(response); ensure304DoesNotContainExtraEntityHeaders(response); identityIsNotUsedInContentEncoding(response); warningsWithNonMatchingWarnDatesAreRemoved(response); } private void consumeBody(final HttpResponse response) throws IOException { final HttpEntity body = response.getEntity(); if (body != null) { IOUtils.consume(body); } } private void warningsWithNonMatchingWarnDatesAreRemoved( final HttpResponse response) { final Date responseDate = DateUtils.parseDate(response.getFirstHeader(HTTP.DATE_HEADER).getValue()); if (responseDate == null) { return; } final Header[] warningHeaders = response.getHeaders(HeaderConstants.WARNING); if (warningHeaders == null || warningHeaders.length == 0) { return; } final List
newWarningHeaders = new ArrayList
(); boolean modified = false; for(final Header h : warningHeaders) { for(final WarningValue wv : WarningValue.getWarningValues(h)) { final Date warnDate = wv.getWarnDate(); if (warnDate == null || warnDate.equals(responseDate)) { newWarningHeaders.add(new BasicHeader(HeaderConstants.WARNING,wv.toString())); } else { modified = true; } } } if (modified) { response.removeHeaders(HeaderConstants.WARNING); for(final Header h : newWarningHeaders) { response.addHeader(h); } } } private void identityIsNotUsedInContentEncoding(final HttpResponse response) { final Header[] hdrs = response.getHeaders(HTTP.CONTENT_ENCODING); if (hdrs == null || hdrs.length == 0) { return; } final List
newHeaders = new ArrayList
(); boolean modified = false; for (final Header h : hdrs) { final StringBuilder buf = new StringBuilder(); boolean first = true; for (final HeaderElement elt : h.getElements()) { if ("identity".equalsIgnoreCase(elt.getName())) { modified = true; } else { if (!first) { buf.append(","); } buf.append(elt.toString()); first = false; } } final String newHeaderValue = buf.toString(); if (!"".equals(newHeaderValue)) { newHeaders.add(new BasicHeader(HTTP.CONTENT_ENCODING, newHeaderValue)); } } if (!modified) { return; } response.removeHeaders(HTTP.CONTENT_ENCODING); for (final Header h : newHeaders) { response.addHeader(h); } } private void ensure206ContainsDateHeader(final HttpResponse response) { if (response.getFirstHeader(HTTP.DATE_HEADER) == null) { response.addHeader(HTTP.DATE_HEADER, DateUtils.formatDate(new Date())); } } private void ensurePartialContentIsNotSentToAClientThatDidNotRequestIt(final HttpRequest request, final HttpResponse response) throws IOException { if (request.getFirstHeader(HeaderConstants.RANGE) != null || response.getStatusLine().getStatusCode() != HttpStatus.SC_PARTIAL_CONTENT) { return; } consumeBody(response); throw new ClientProtocolException(UNEXPECTED_PARTIAL_CONTENT); } private void ensure200ForOPTIONSRequestWithNoBodyHasContentLengthZero(final HttpRequest request, final HttpResponse response) { if (!request.getRequestLine().getMethod().equalsIgnoreCase(HeaderConstants.OPTIONS_METHOD)) { return; } if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { return; } if (response.getFirstHeader(HTTP.CONTENT_LEN) == null) { response.addHeader(HTTP.CONTENT_LEN, "0"); } } private void ensure304DoesNotContainExtraEntityHeaders(final HttpResponse response) { final String[] disallowedEntityHeaders = { HeaderConstants.ALLOW, HTTP.CONTENT_ENCODING, "Content-Language", HTTP.CONTENT_LEN, "Content-MD5", "Content-Range", HTTP.CONTENT_TYPE, HeaderConstants.LAST_MODIFIED }; if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_MODIFIED) { for(final String hdr : disallowedEntityHeaders) { response.removeHeaders(hdr); } } } private boolean backendResponseMustNotHaveBody(final HttpRequest request, final HttpResponse backendResponse) { return HeaderConstants.HEAD_METHOD.equals(request.getRequestLine().getMethod()) || backendResponse.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT || backendResponse.getStatusLine().getStatusCode() == HttpStatus.SC_RESET_CONTENT || backendResponse.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_MODIFIED; } private void requestDidNotExpect100ContinueButResponseIsOne(final HttpRequestWrapper request, final HttpResponse response) throws IOException { if (response.getStatusLine().getStatusCode() != HttpStatus.SC_CONTINUE) { return; } final HttpRequest originalRequest = request.getOriginal(); if (originalRequest instanceof HttpEntityEnclosingRequest) { if (((HttpEntityEnclosingRequest)originalRequest).expectContinue()) { return; } } consumeBody(response); throw new ClientProtocolException(UNEXPECTED_100_CONTINUE); } private void transferEncodingIsNotReturnedTo1_0Client(final HttpRequestWrapper request, final HttpResponse response) { final HttpRequest originalRequest = request.getOriginal(); if (originalRequest.getProtocolVersion().compareToVersion(HttpVersion.HTTP_1_1) >= 0) { return; } removeResponseTransferEncoding(response); } private void removeResponseTransferEncoding(final HttpResponse response) { response.removeHeaders("TE"); response.removeHeaders(HTTP.TRANSFER_ENCODING); } } ././@LongLink0100644 0000000 0000000 00000000167 12302131606 011631 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ResponseProxyHandler.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Respons0100644 0000000 0000000 00000005352 12301751724 032320 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.Closeable; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.http.HttpResponse; import org.apache.http.annotation.NotThreadSafe; /** * A proxy class that can enhance an arbitrary {@link HttpResponse} with * {@link Closeable#close()} method. * * @since 4.3 */ @NotThreadSafe class ResponseProxyHandler implements InvocationHandler { private static final Method CLOSE_METHOD; static { try { CLOSE_METHOD = Closeable.class.getMethod("close"); } catch (final NoSuchMethodException ex) { throw new Error(ex); } } private final HttpResponse original; ResponseProxyHandler(final HttpResponse original) { super(); this.original = original; } public void close() throws IOException { IOUtils.consume(original.getEntity()); } public Object invoke( final Object proxy, final Method method, final Object[] args) throws Throwable { if (method.equals(CLOSE_METHOD)) { close(); return null; } else { try { return method.invoke(this.original, args); } catch (final InvocationTargetException ex) { final Throwable cause = ex.getCause(); if (cause != null) { throw cause; } else { throw ex; } } } } } ././@LongLink0100644 0000000 0000000 00000000165 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/SchedulingStrategy.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Schedul0100644 0000000 0000000 00000003336 12301751724 032256 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.Closeable; /** * Specifies when revalidation requests are scheduled. * * @since 4.3 */ public interface SchedulingStrategy extends Closeable { /** * Schedule an {@link AsynchronousValidationRequest} to be executed. * * @param revalidationRequest the request to be executed; not null * @throws java.util.concurrent.RejectedExecutionException if the request could not be scheduled for execution */ void schedule(AsynchronousValidationRequest revalidationRequest); } ././@LongLink0100644 0000000 0000000 00000000174 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/SizeLimitedResponseReader.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/SizeLim0100644 0000000 0000000 00000011653 12301751724 032244 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Proxy; import org.apache.http.HttpEntity; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.client.cache.InputLimit; import org.apache.http.client.cache.Resource; import org.apache.http.client.cache.ResourceFactory; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.message.BasicHttpResponse; /** * @since 4.1 */ @NotThreadSafe class SizeLimitedResponseReader { private final ResourceFactory resourceFactory; private final long maxResponseSizeBytes; private final HttpRequest request; private final CloseableHttpResponse response; private InputStream instream; private InputLimit limit; private Resource resource; private boolean consumed; /** * Create an {@link HttpResponse} that is limited in size, this allows for checking * the size of objects that will be stored in the cache. */ public SizeLimitedResponseReader( final ResourceFactory resourceFactory, final long maxResponseSizeBytes, final HttpRequest request, final CloseableHttpResponse response) { super(); this.resourceFactory = resourceFactory; this.maxResponseSizeBytes = maxResponseSizeBytes; this.request = request; this.response = response; } protected void readResponse() throws IOException { if (!consumed) { doConsume(); } } private void ensureNotConsumed() { if (consumed) { throw new IllegalStateException("Response has already been consumed"); } } private void ensureConsumed() { if (!consumed) { throw new IllegalStateException("Response has not been consumed"); } } private void doConsume() throws IOException { ensureNotConsumed(); consumed = true; limit = new InputLimit(maxResponseSizeBytes); final HttpEntity entity = response.getEntity(); if (entity == null) { return; } final String uri = request.getRequestLine().getUri(); instream = entity.getContent(); try { resource = resourceFactory.generate(uri, instream, limit); } finally { if (!limit.isReached()) { instream.close(); } } } boolean isLimitReached() { ensureConsumed(); return limit.isReached(); } Resource getResource() { ensureConsumed(); return resource; } CloseableHttpResponse getReconstructedResponse() throws IOException { ensureConsumed(); final HttpResponse reconstructed = new BasicHttpResponse(response.getStatusLine()); reconstructed.setHeaders(response.getAllHeaders()); final CombinedEntity combinedEntity = new CombinedEntity(resource, instream); final HttpEntity entity = response.getEntity(); if (entity != null) { combinedEntity.setContentType(entity.getContentType()); combinedEntity.setContentEncoding(entity.getContentEncoding()); combinedEntity.setChunked(entity.isChunked()); } reconstructed.setEntity(combinedEntity); return (CloseableHttpResponse) Proxy.newProxyInstance( ResponseProxyHandler.class.getClassLoader(), new Class[] { CloseableHttpResponse.class }, new ResponseProxyHandler(reconstructed) { @Override public void close() throws IOException { response.close(); } }); } } ././@LongLink0100644 0000000 0000000 00000000152 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Variant.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Variant0100644 0000000 0000000 00000003535 12301751724 032274 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.apache.http.client.cache.HttpCacheEntry; /** Records a set of information describing a cached variant. */ class Variant { private final String variantKey; private final String cacheKey; private final HttpCacheEntry entry; public Variant(final String variantKey, final String cacheKey, final HttpCacheEntry entry) { this.variantKey = variantKey; this.cacheKey = cacheKey; this.entry = entry; } public String getVariantKey() { return variantKey; } public String getCacheKey() { return cacheKey; } public HttpCacheEntry getEntry() { return entry; } } ././@LongLink0100644 0000000 0000000 00000000157 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/WarningValue.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/Warning0100644 0000000 0000000 00000030507 12301751724 032274 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.http.Header; import org.apache.http.client.utils.DateUtils; /** This class provides for parsing and understanding Warning headers. As * the Warning header can be multi-valued, but the values can contain * separators like commas inside quoted strings, we cannot use the regular * {@link Header#getElements()} call to access the values. */ class WarningValue { private int offs; private int init_offs; private final String src; private int warnCode; private String warnAgent; private String warnText; private Date warnDate; WarningValue(final String s) { this(s, 0); } WarningValue(final String s, final int offs) { this.offs = this.init_offs = offs; this.src = s; consumeWarnValue(); } /** Returns an array of the parseable warning values contained * in the given header value, which is assumed to be a * Warning header. Improperly formatted warning values will be * skipped, in keeping with the philosophy of "ignore what you * cannot understand." * @param h Warning {@link Header} to parse * @return array of WarnValue objects */ public static WarningValue[] getWarningValues(final Header h) { final List out = new ArrayList(); final String src = h.getValue(); int offs = 0; while(offs < src.length()) { try { final WarningValue wv = new WarningValue(src, offs); out.add(wv); offs = wv.offs; } catch (final IllegalArgumentException e) { final int nextComma = src.indexOf(',', offs); if (nextComma == -1) { break; } offs = nextComma + 1; } } final WarningValue[] wvs = {}; return out.toArray(wvs); } /* * LWS = [CRLF] 1*( SP | HT ) * CRLF = CR LF */ protected void consumeLinearWhitespace() { while(offs < src.length()) { switch(src.charAt(offs)) { case '\r': if (offs+2 >= src.length() || src.charAt(offs+1) != '\n' || (src.charAt(offs+2) != ' ' && src.charAt(offs+2) != '\t')) { return; } offs += 2; break; case ' ': case '\t': break; default: return; } offs++; } } /* * CHAR = */ private boolean isChar(final char c) { final int i = c; return (i >= 0 && i <= 127); } /* * CTL = */ private boolean isControl(final char c) { final int i = c; return (i == 127 || (i >=0 && i <= 31)); } /* * separators = "(" | ")" | "<" | ">" | "@" * | "," | ";" | ":" | "\" | <"> * | "/" | "[" | "]" | "?" | "=" * | "{" | "}" | SP | HT */ private boolean isSeparator(final char c) { return (c == '(' || c == ')' || c == '<' || c == '>' || c == '@' || c == ',' || c == ';' || c == ':' || c == '\\' || c == '\"' || c == '/' || c == '[' || c == ']' || c == '?' || c == '=' || c == '{' || c == '}' || c == ' ' || c == '\t'); } /* * token = 1* */ protected void consumeToken() { if (!isTokenChar(src.charAt(offs))) { parseError(); } while(offs < src.length()) { if (!isTokenChar(src.charAt(offs))) { break; } offs++; } } private boolean isTokenChar(final char c) { return (isChar(c) && !isControl(c) && !isSeparator(c)); } private static final String TOPLABEL = "\\p{Alpha}([\\p{Alnum}-]*\\p{Alnum})?"; private static final String DOMAINLABEL = "\\p{Alnum}([\\p{Alnum}-]*\\p{Alnum})?"; private static final String HOSTNAME = "(" + DOMAINLABEL + "\\.)*" + TOPLABEL + "\\.?"; private static final String IPV4ADDRESS = "\\d+\\.\\d+\\.\\d+\\.\\d+"; private static final String HOST = "(" + HOSTNAME + ")|(" + IPV4ADDRESS + ")"; private static final String PORT = "\\d*"; private static final String HOSTPORT = "(" + HOST + ")(\\:" + PORT + ")?"; private static final Pattern HOSTPORT_PATTERN = Pattern.compile(HOSTPORT); protected void consumeHostPort() { final Matcher m = HOSTPORT_PATTERN.matcher(src.substring(offs)); if (!m.find()) { parseError(); } if (m.start() != 0) { parseError(); } offs += m.end(); } /* * warn-agent = ( host [ ":" port ] ) | pseudonym * pseudonym = token */ protected void consumeWarnAgent() { final int curr_offs = offs; try { consumeHostPort(); warnAgent = src.substring(curr_offs, offs); consumeCharacter(' '); return; } catch (final IllegalArgumentException e) { offs = curr_offs; } consumeToken(); warnAgent = src.substring(curr_offs, offs); consumeCharacter(' '); } /* * quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) * qdtext = > */ protected void consumeQuotedString() { if (src.charAt(offs) != '\"') { parseError(); } offs++; boolean foundEnd = false; while(offs < src.length() && !foundEnd) { final char c = src.charAt(offs); if (offs + 1 < src.length() && c == '\\' && isChar(src.charAt(offs+1))) { offs += 2; // consume quoted-pair } else if (c == '\"') { foundEnd = true; offs++; } else if (c != '\"' && !isControl(c)) { offs++; } else { parseError(); } } if (!foundEnd) { parseError(); } } /* * warn-text = quoted-string */ protected void consumeWarnText() { final int curr = offs; consumeQuotedString(); warnText = src.substring(curr, offs); } private static final String MONTH = "Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec"; private static final String WEEKDAY = "Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday"; private static final String WKDAY = "Mon|Tue|Wed|Thu|Fri|Sat|Sun"; private static final String TIME = "\\d{2}:\\d{2}:\\d{2}"; private static final String DATE3 = "(" + MONTH + ") ( |\\d)\\d"; private static final String DATE2 = "\\d{2}-(" + MONTH + ")-\\d{2}"; private static final String DATE1 = "\\d{2} (" + MONTH + ") \\d{4}"; private static final String ASCTIME_DATE = "(" + WKDAY + ") (" + DATE3 + ") (" + TIME + ") \\d{4}"; private static final String RFC850_DATE = "(" + WEEKDAY + "), (" + DATE2 + ") (" + TIME + ") GMT"; private static final String RFC1123_DATE = "(" + WKDAY + "), (" + DATE1 + ") (" + TIME + ") GMT"; private static final String HTTP_DATE = "(" + RFC1123_DATE + ")|(" + RFC850_DATE + ")|(" + ASCTIME_DATE + ")"; private static final String WARN_DATE = "\"(" + HTTP_DATE + ")\""; private static final Pattern WARN_DATE_PATTERN = Pattern.compile(WARN_DATE); /* * warn-date = <"> HTTP-date <"> */ protected void consumeWarnDate() { final int curr = offs; final Matcher m = WARN_DATE_PATTERN.matcher(src.substring(offs)); if (!m.lookingAt()) { parseError(); } offs += m.end(); warnDate = DateUtils.parseDate(src.substring(curr+1,offs-1)); } /* * warning-value = warn-code SP warn-agent SP warn-text [SP warn-date] */ protected void consumeWarnValue() { consumeLinearWhitespace(); consumeWarnCode(); consumeWarnAgent(); consumeWarnText(); if (offs + 1 < src.length() && src.charAt(offs) == ' ' && src.charAt(offs+1) == '\"') { consumeCharacter(' '); consumeWarnDate(); } consumeLinearWhitespace(); if (offs != src.length()) { consumeCharacter(','); } } protected void consumeCharacter(final char c) { if (offs + 1 > src.length() || c != src.charAt(offs)) { parseError(); } offs++; } /* * warn-code = 3DIGIT */ protected void consumeWarnCode() { if (offs + 4 > src.length() || !Character.isDigit(src.charAt(offs)) || !Character.isDigit(src.charAt(offs + 1)) || !Character.isDigit(src.charAt(offs + 2)) || src.charAt(offs + 3) != ' ') { parseError(); } warnCode = Integer.parseInt(src.substring(offs,offs+3)); offs += 4; } private void parseError() { final String s = src.substring(init_offs); throw new IllegalArgumentException("Bad warn code \"" + s + "\""); } /** Returns the 3-digit code associated with this warning. * @return int */ public int getWarnCode() { return warnCode; } /** Returns the "warn-agent" string associated with this warning, * which is either the name or pseudonym of the server that added * this particular Warning header. * @return {@link String} */ public String getWarnAgent() { return warnAgent; } /** Returns the human-readable warning text for this warning. Note * that the original quoted-string is returned here, including * escaping for any contained characters. In other words, if the * header was: *
     *   Warning: 110 fred "Response is stale"
     * 
* then this method will return "\"Response is stale\"" * (surrounding quotes included). * @return {@link String} */ public String getWarnText() { return warnText; } /** Returns the date and time when this warning was added, or * null if a warning date was not supplied in the * header. * @return {@link Date} */ public Date getWarnDate() { return warnDate; } /** Formats a WarningValue as a {@link String} * suitable for including in a header. For example, you can: *
     *   WarningValue wv = ...;
     *   HttpResponse resp = ...;
     *   resp.addHeader("Warning", wv.toString());
     * 
* @return {@link String} */ @Override public String toString() { if (warnDate != null) { return String.format("%d %s %s \"%s\"", warnCode, warnAgent, warnText, DateUtils.formatDate(warnDate)); } else { return String.format("%d %s %s", warnCode, warnAgent, warnText); } } } ././@LongLink0100644 0000000 0000000 00000000146 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ehcache/httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ehcache0040755 0000000 0000000 00000000000 12301751722 032241 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000202 12302131606 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ehcache/EhcacheHttpCacheStorage.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ehcache0100644 0000000 0000000 00000014663 12301751722 032252 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.ehcache; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import net.sf.ehcache.Ehcache; import net.sf.ehcache.Element; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheEntrySerializer; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.client.cache.HttpCacheUpdateCallback; import org.apache.http.client.cache.HttpCacheUpdateException; import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.DefaultHttpCacheEntrySerializer; /** *

This class is a storage backend for cache entries that uses the * popular Ehcache cache implementation. * In particular, this backend allows for spillover to disk, where the * cache can be effectively larger than memory, and cached responses are * paged into and out of memory from disk as needed.

* *

N.B. Since the Ehcache is configured ahead of time with a * maximum number of cache entries, this effectively ignores the * {@link CacheConfig#setMaxCacheEntries(int) maximum cache entries} * specified by a provided {@link CacheConfig}.

* *

Please refer to the * Ehcache documentation for details on how to configure the Ehcache * itself.

* @since 4.1 */ public class EhcacheHttpCacheStorage implements HttpCacheStorage { private final Ehcache cache; private final HttpCacheEntrySerializer serializer; private final int maxUpdateRetries; /** * Constructs a storage backend using the provided Ehcache * with default configuration options. * @param cache where to store cached origin responses */ public EhcacheHttpCacheStorage(final Ehcache cache) { this(cache, CacheConfig.DEFAULT, new DefaultHttpCacheEntrySerializer()); } /** * Constructs a storage backend using the provided Ehcache * with the given configuration options. * @param cache where to store cached origin responses * @param config cache storage configuration options - note that * the setting for max object size will be ignored and * should be configured in the Ehcache instead. */ public EhcacheHttpCacheStorage(final Ehcache cache, final CacheConfig config){ this(cache, config, new DefaultHttpCacheEntrySerializer()); } /** * Constructs a storage backend using the provided Ehcache * with the given configuration options, but using an alternative * cache entry serialization strategy. * @param cache where to store cached origin responses * @param config cache storage configuration options - note that * the setting for max object size will be ignored and * should be configured in the Ehcache instead. * @param serializer alternative serialization mechanism */ public EhcacheHttpCacheStorage(final Ehcache cache, final CacheConfig config, final HttpCacheEntrySerializer serializer){ this.cache = cache; this.maxUpdateRetries = config.getMaxUpdateRetries(); this.serializer = serializer; } public synchronized void putEntry(final String key, final HttpCacheEntry entry) throws IOException { final ByteArrayOutputStream bos = new ByteArrayOutputStream(); serializer.writeTo(entry, bos); cache.put(new Element(key, bos.toByteArray())); } public synchronized HttpCacheEntry getEntry(final String key) throws IOException { final Element e = cache.get(key); if(e == null){ return null; } final byte[] data = (byte[])e.getValue(); return serializer.readFrom(new ByteArrayInputStream(data)); } public synchronized void removeEntry(final String key) { cache.remove(key); } public synchronized void updateEntry(final String key, final HttpCacheUpdateCallback callback) throws IOException, HttpCacheUpdateException { int numRetries = 0; do{ final Element oldElement = cache.get(key); HttpCacheEntry existingEntry = null; if(oldElement != null){ final byte[] data = (byte[])oldElement.getValue(); existingEntry = serializer.readFrom(new ByteArrayInputStream(data)); } final HttpCacheEntry updatedEntry = callback.update(existingEntry); if (existingEntry == null) { putEntry(key, updatedEntry); return; } else { // Attempt to do a CAS replace, if we fail then retry // While this operation should work fine within this instance, multiple instances // could trample each others' data final ByteArrayOutputStream bos = new ByteArrayOutputStream(); serializer.writeTo(updatedEntry, bos); final Element newElement = new Element(key, bos.toByteArray()); if (cache.replace(oldElement, newElement)) { return; }else{ numRetries++; } } }while(numRetries <= maxUpdateRetries); throw new HttpCacheUpdateException("Failed to update"); } } ././@LongLink0100644 0000000 0000000 00000000162 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ehcache/package.htmlhttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/ehcache0100644 0000000 0000000 00000002662 12301751722 032246 0ustar000000000 0000000

This package contains a storage backend based on Ehcache that can be plugged into a {@link org.apache.http.impl.client.cache.CachingHttpClient} and used for storing cache entries.

././@LongLink0100644 0000000 0000000 00000000150 12302131606 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcached/httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcach0040755 0000000 0000000 00000000000 12301751720 032254 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000175 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcached/KeyHashingScheme.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000006343 12301751720 032261 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */package org.apache.http.impl.client.cache.memcached; /** * Since the {@link org.apache.http.client.cache.HttpCacheStorage} interface * expects to use variant-annotated URLs for its storage keys, but Memcached * has a maximum key size, we need to support mapping storage keys to cache * keys. Clients can implement this interface to change the way the mapping * is done (for example, to add a prefix to all cache keys to provide a form * of memcached namespacing). */ public interface KeyHashingScheme { /** Maps a storage key to a cache key. The storage key is what * the higher-level HTTP cache uses as a key; the cache key is what * we use as a key for talking to memcached. * @param storageKey what the higher-level HTTP cache wants to use * as its key for looking up cache entries * @return a cache key suitable for use with memcached */ public String hash(String storageKey); } ././@LongLink0100644 0000000 0000000 00000000200 12302131606 011615 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcached/MemcachedCacheEntry.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000005765 12301751720 032270 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; import org.apache.http.client.cache.HttpCacheEntry; /** * Provides for serialization and deserialization of higher-level * {@link HttpCacheEntry} objects into byte arrays suitable for * storage in memcached. Clients wishing to change the serialization * mechanism from the provided defaults should implement this * interface as well as {@link MemcachedCacheEntryFactory}. */ public interface MemcachedCacheEntry { /** * Returns a serialized representation of the current cache entry. */ byte[] toByteArray(); /** * Returns the storage key associated with this entry. May return * null if this is an "unset" instance waiting to be * {@link #set(byte[])} with a serialized representation. */ String getStorageKey(); /** * Returns the {@link HttpCacheEntry} associated with this entry. * May return null if this is an "unset" instance * waiting to be {@link #set(byte[])} with a serialized * representation. */ HttpCacheEntry getHttpCacheEntry(); /** * Given a serialized representation of a {@link MemcachedCacheEntry}, * attempt to reconstitute the storage key and {@link HttpCacheEntry} * represented therein. After a successful call to this method, this * object should return updated (as appropriate) values for * {@link #getStorageKey()} and {@link #getHttpCacheEntry()}. This * should be viewed as an atomic operation on the * MemcachedCacheEntry. * @param bytes serialized representation * @throws {@link MemcachedSerializationException} if deserialization * fails. In this case, the prior values for {{@link #getStorageKey()} * and {@link #getHttpCacheEntry()} should remain unchanged. */ void set(byte[] bytes); } ././@LongLink0100644 0000000 0000000 00000000207 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcached/MemcachedCacheEntryFactory.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000005122 12301751720 032253 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; import org.apache.http.client.cache.HttpCacheEntry; /** * Creates {@link MemcachedCacheEntry} instances that can be used for * serializing and deserializing {@link HttpCacheEntry} instances for * storage in memcached. */ public interface MemcachedCacheEntryFactory { /** * Creates a new {@link MemcachedCacheEntry} for storing the * given {@link HttpCacheEntry} under the given storage key. Since * we are hashing storage keys into cache keys to accommodate * limitations in memcached's key space, it is possible to have * cache collisions. Therefore, we store the storage key along * with the HttpCacheEntry so it can be compared * on retrieval and thus detect collisions. * @param storageKey storage key under which the entry will * be logically stored * @param entry the cache entry to store * @return a {@link MemcachedCacheEntry} ready to provide * a serialized representation */ MemcachedCacheEntry getMemcachedCacheEntry(String storageKey, HttpCacheEntry entry); /** * Creates an "unset" {@link MemcachedCacheEntry} ready to accept * a serialized representation via {@link MemcachedCacheEntry#set(byte[])} * and deserialize it into a storage key and a {@link HttpCacheEntry}. * @return MemcachedCacheEntry */ MemcachedCacheEntry getUnsetCacheEntry(); } ././@LongLink0100644 0000000 0000000 00000000213 12302131606 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcached/MemcachedCacheEntryFactoryImpl.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000003304 12301751720 032253 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; import org.apache.http.client.cache.HttpCacheEntry; /** * Default implementation of {@link MemcachedCacheEntryFactory}. */ public class MemcachedCacheEntryFactoryImpl implements MemcachedCacheEntryFactory { public MemcachedCacheEntry getMemcachedCacheEntry(final String key, final HttpCacheEntry entry) { return new MemcachedCacheEntryImpl(key, entry); } public MemcachedCacheEntry getUnsetCacheEntry() { return new MemcachedCacheEntryImpl(null, null); } } ././@LongLink0100644 0000000 0000000 00000000204 12302131606 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcached/MemcachedCacheEntryImpl.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000007431 12301751720 032260 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.apache.http.client.cache.HttpCacheEntry; /** * Default implementation of {@link MemcachedCacheEntry}. This implementation * simply uses Java serialization to serialize the storage key followed by * the {@link HttpCacheEntry} into a byte array. */ public class MemcachedCacheEntryImpl implements MemcachedCacheEntry { private String key; private HttpCacheEntry httpCacheEntry; public MemcachedCacheEntryImpl(final String key, final HttpCacheEntry httpCacheEntry) { this.key = key; this.httpCacheEntry = httpCacheEntry; } public MemcachedCacheEntryImpl() { } /* (non-Javadoc) * @see org.apache.http.impl.client.cache.memcached.MemcachedCacheEntry#toByteArray() */ synchronized public byte[] toByteArray() { final ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos; try { oos = new ObjectOutputStream(bos); oos.writeObject(this.key); oos.writeObject(this.httpCacheEntry); oos.close(); } catch (final IOException ioe) { throw new MemcachedSerializationException(ioe); } return bos.toByteArray(); } /* (non-Javadoc) * @see org.apache.http.impl.client.cache.memcached.MemcachedCacheEntry#getKey() */ public synchronized String getStorageKey() { return key; } /* (non-Javadoc) * @see org.apache.http.impl.client.cache.memcached.MemcachedCacheEntry#getHttpCacheEntry() */ public synchronized HttpCacheEntry getHttpCacheEntry() { return httpCacheEntry; } /* (non-Javadoc) * @see org.apache.http.impl.client.cache.memcached.MemcachedCacheEntry#set(byte[]) */ synchronized public void set(final byte[] bytes) { final ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois; String s; HttpCacheEntry entry; try { ois = new ObjectInputStream(bis); s = (String)ois.readObject(); entry = (HttpCacheEntry)ois.readObject(); ois.close(); bis.close(); } catch (final IOException ioe) { throw new MemcachedSerializationException(ioe); } catch (final ClassNotFoundException cnfe) { throw new MemcachedSerializationException(cnfe); } this.key = s; this.httpCacheEntry = entry; } } ././@LongLink0100644 0000000 0000000 00000000206 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcached/MemcachedHttpCacheStorage.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000027335 12301751720 032265 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; import java.io.IOException; import java.net.InetSocketAddress; import net.spy.memcached.CASResponse; import net.spy.memcached.CASValue; import net.spy.memcached.MemcachedClient; import net.spy.memcached.MemcachedClientIF; import net.spy.memcached.OperationTimeoutException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheEntrySerializer; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.client.cache.HttpCacheUpdateCallback; import org.apache.http.client.cache.HttpCacheUpdateException; import org.apache.http.impl.client.cache.CacheConfig; /** *

This class is a storage backend that uses an external memcached * for storing cached origin responses. This storage option provides a * couple of interesting advantages over the default in-memory storage * backend: *

    *
  1. in-memory cached objects can survive an application restart since * they are held in a separate process
  2. *
  3. it becomes possible for several cooperating applications to share * a large memcached farm together
  4. *
* Note that in a shared memcached pool setting you may wish to make use * of the Ketama consistent hashing algorithm to reduce the number of * cache misses that might result if one of the memcached cluster members * fails (see the * KetamaConnectionFactory). *

* *

Because memcached places limits on the size of its keys, we need to * introduce a key hashing scheme to map the annotated URLs the higher-level * caching HTTP client wants to use as keys onto ones that are suitable * for use with memcached. Please see {@link KeyHashingScheme} if you would * like to use something other than the provided {@link SHA256KeyHashingScheme}.

* *

Because this hashing scheme can potentially result in key collisions (though * highly unlikely), we need to store the higher-level logical storage key along * with the {@link HttpCacheEntry} so that we can re-check it on retrieval. There * is a default serialization scheme provided for this, although you can provide * your own implementations of {@link MemcachedCacheEntry} and * {@link MemcachedCacheEntryFactory} to customize this serialization.

* *

Please refer to the * memcached documentation and in particular to the documentation for * the spymemcached * documentation for details about how to set up and configure memcached * and the Java client used here, respectively.

* * @since 4.1 */ public class MemcachedHttpCacheStorage implements HttpCacheStorage { private static final Log log = LogFactory.getLog(MemcachedHttpCacheStorage.class); private final MemcachedClientIF client; private final KeyHashingScheme keyHashingScheme; private final MemcachedCacheEntryFactory memcachedCacheEntryFactory; private final int maxUpdateRetries; /** * Create a storage backend talking to a memcached instance * listening on the specified host and port. This is useful if you * just have a single local memcached instance running on the same * machine as your application, for example. * @param address where the memcached daemon is running * @throws IOException in case of an error */ public MemcachedHttpCacheStorage(final InetSocketAddress address) throws IOException { this(new MemcachedClient(address)); } /** * Create a storage backend using the pre-configured given * memcached client. * @param cache client to use for communicating with memcached */ public MemcachedHttpCacheStorage(final MemcachedClientIF cache) { this(cache, CacheConfig.DEFAULT, new MemcachedCacheEntryFactoryImpl(), new SHA256KeyHashingScheme()); } /** * Create a storage backend using the given memcached client and * applying the given cache configuration and cache entry serialization * mechanism. Deprecation note: In the process of fixing a bug * based on the need to hash logical storage keys onto memcached cache * keys, the serialization process was revamped. This constructor still * works, but the serializer argument will be ignored and default * implementations of the new framework will be used. You can still * provide custom serialization by using the * {@link #MemcachedHttpCacheStorage(MemcachedClientIF, CacheConfig, * MemcachedCacheEntryFactory, KeyHashingScheme)} constructor. * @param client how to talk to memcached * @param config apply HTTP cache-related options * @param serializer ignored * * @deprecated (4.2) do not use */ @Deprecated public MemcachedHttpCacheStorage(final MemcachedClientIF client, final CacheConfig config, final HttpCacheEntrySerializer serializer) { this(client, config, new MemcachedCacheEntryFactoryImpl(), new SHA256KeyHashingScheme()); } /** * Create a storage backend using the given memcached client and * applying the given cache configuration, serialization, and hashing * mechanisms. * @param client how to talk to memcached * @param config apply HTTP cache-related options * @param memcachedCacheEntryFactory Factory pattern used for obtaining * instances of alternative cache entry serialization mechanisms * @param keyHashingScheme how to map higher-level logical "storage keys" * onto "cache keys" suitable for use with memcached */ public MemcachedHttpCacheStorage(final MemcachedClientIF client, final CacheConfig config, final MemcachedCacheEntryFactory memcachedCacheEntryFactory, final KeyHashingScheme keyHashingScheme) { this.client = client; this.maxUpdateRetries = config.getMaxUpdateRetries(); this.memcachedCacheEntryFactory = memcachedCacheEntryFactory; this.keyHashingScheme = keyHashingScheme; } public void putEntry(final String url, final HttpCacheEntry entry) throws IOException { final byte[] bytes = serializeEntry(url, entry); final String key = getCacheKey(url); if (key == null) { return; } try { client.set(key, 0, bytes); } catch (final OperationTimeoutException ex) { throw new MemcachedOperationTimeoutException(ex); } } private String getCacheKey(final String url) { try { return keyHashingScheme.hash(url); } catch (final MemcachedKeyHashingException mkhe) { return null; } } private byte[] serializeEntry(final String url, final HttpCacheEntry hce) throws IOException { final MemcachedCacheEntry mce = memcachedCacheEntryFactory.getMemcachedCacheEntry(url, hce); try { return mce.toByteArray(); } catch (final MemcachedSerializationException mse) { final IOException ioe = new IOException(); ioe.initCause(mse); throw ioe; } } private byte[] convertToByteArray(final Object o) { if (o == null) { return null; } if (!(o instanceof byte[])) { log.warn("got a non-bytearray back from memcached: " + o); return null; } return (byte[])o; } private MemcachedCacheEntry reconstituteEntry(final Object o) { final byte[] bytes = convertToByteArray(o); if (bytes == null) { return null; } final MemcachedCacheEntry mce = memcachedCacheEntryFactory.getUnsetCacheEntry(); try { mce.set(bytes); } catch (final MemcachedSerializationException mse) { return null; } return mce; } public HttpCacheEntry getEntry(final String url) throws IOException { final String key = getCacheKey(url); if (key == null) { return null; } try { final MemcachedCacheEntry mce = reconstituteEntry(client.get(key)); if (mce == null || !url.equals(mce.getStorageKey())) { return null; } return mce.getHttpCacheEntry(); } catch (final OperationTimeoutException ex) { throw new MemcachedOperationTimeoutException(ex); } } public void removeEntry(final String url) throws IOException { final String key = getCacheKey(url); if (key == null) { return; } try { client.delete(key); } catch (final OperationTimeoutException ex) { throw new MemcachedOperationTimeoutException(ex); } } public void updateEntry(final String url, final HttpCacheUpdateCallback callback) throws HttpCacheUpdateException, IOException { int numRetries = 0; final String key = getCacheKey(url); if (key == null) { throw new HttpCacheUpdateException("couldn't generate cache key"); } do { try { final CASValue v = client.gets(key); MemcachedCacheEntry mce = (v == null) ? null : reconstituteEntry(v.getValue()); if (mce != null && (!url.equals(mce.getStorageKey()))) { mce = null; } final HttpCacheEntry existingEntry = (mce == null) ? null : mce.getHttpCacheEntry(); final HttpCacheEntry updatedEntry = callback.update(existingEntry); if (existingEntry == null) { putEntry(url, updatedEntry); return; } else { final byte[] updatedBytes = serializeEntry(url, updatedEntry); final CASResponse casResult = client.cas(key, v.getCas(), updatedBytes); if (casResult != CASResponse.OK) { numRetries++; } else { return; } } } catch (final OperationTimeoutException ex) { throw new MemcachedOperationTimeoutException(ex); } } while (numRetries <= maxUpdateRetries); throw new HttpCacheUpdateException("Failed to update"); } } ././@LongLink0100644 0000000 0000000 00000000211 12302131606 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcached/MemcachedKeyHashingException.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000003122 12301751720 032251 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; /** * Indicates a problem encountered when trying to map a * logical "storage key" to a "cache key" suitable for use with * memcached. */ public class MemcachedKeyHashingException extends RuntimeException { private static final long serialVersionUID = -7553380015989141114L; public MemcachedKeyHashingException(final Throwable cause) { super(cause); } } ././@LongLink0100644 0000000 0000000 00000000217 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcached/MemcachedOperationTimeoutException.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000003072 12301751720 032255 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; import java.io.IOException; /** * Raised when memcached times out on us. */ class MemcachedOperationTimeoutException extends IOException { private static final long serialVersionUID = 1608334789051537010L; public MemcachedOperationTimeoutException(final Throwable cause) { super(cause.getMessage()); initCause(cause); } } ././@LongLink0100644 0000000 0000000 00000000214 12302131606 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcached/MemcachedSerializationException.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000003135 12301751720 032255 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; /** * Raised when there is a problem serializing or deserializing cache * entries into a byte representation suitable for memcached storage. */ public class MemcachedSerializationException extends RuntimeException { private static final long serialVersionUID = 2201652990656412236L; public MemcachedSerializationException(final Throwable cause) { super(cause); } } ././@LongLink0100644 0000000 0000000 00000000164 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcached/package.htmlhttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000002666 12301751720 032265 0ustar000000000 0000000

This package contains a storage backend based on memcached that can be plugged into a {@link org.apache.http.impl.client.cache.CachingHttpClient} and used for storing cache entries.

././@LongLink0100644 0000000 0000000 00000000203 12302131606 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcached/PrefixKeyHashingScheme.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000004421 12301751720 032254 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; /** * This is a {@link KeyHashingScheme} decorator that simply adds * a known prefix to the results of another KeyHashingScheme. * Primarily useful for namespacing a shared memcached cluster, for * example. */ public class PrefixKeyHashingScheme implements KeyHashingScheme { private final String prefix; private final KeyHashingScheme backingScheme; /** * Creates a new {@link KeyHashingScheme} that prepends the given * prefix to the results of hashes from the given backing scheme. * Users should be aware that memcached has a fixed maximum key * length, so the combination of this prefix plus the results of * the backing hashing scheme must still fit within these limits. * @param prefix * @param backingScheme */ public PrefixKeyHashingScheme(final String prefix, final KeyHashingScheme backingScheme) { this.prefix = prefix; this.backingScheme = backingScheme; } public String hash(final String storageKey) { return prefix + backingScheme.hash(storageKey); } } ././@LongLink0100644 0000000 0000000 00000000203 12302131606 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcached/SHA256KeyHashingScheme.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000004463 12301751720 032262 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.apache.commons.codec.binary.Hex; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * This is a {@link KeyHashingScheme} based on the * SHA-256 * algorithm. The hashes produced are hex-encoded SHA-256 * digests and hence are always 64-character hexadecimal * strings. */ public class SHA256KeyHashingScheme implements KeyHashingScheme { private static final Log log = LogFactory.getLog(SHA256KeyHashingScheme.class); public String hash(final String key) { final MessageDigest md = getDigest(); md.update(key.getBytes()); return Hex.encodeHexString(md.digest()); } private MessageDigest getDigest() { try { return MessageDigest.getInstance("SHA-256"); } catch (final NoSuchAlgorithmException nsae) { log.error("can't find SHA-256 implementation for cache key hashing"); throw new MemcachedKeyHashingException(nsae); } } } httpcomponents-client-4.3.3/httpclient-cache/src/main/java-deprecated/0040755 0000000 0000000 00000000000 12301751716 024570 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java-deprecated/org/0040755 0000000 0000000 00000000000 12301751716 025357 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java-deprecated/org/apache/0040755 0000000 0000000 00000000000 12301751716 026600 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java-deprecated/org/apache/http/0040755 0000000 0000000 00000000000 12301751716 027557 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java-deprecated/org/apache/http/impl/0040755 0000000 0000000 00000000000 12301751716 030520 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java-deprecated/org/apache/http/impl/client/0040755 0000000 0000000 00000000000 12301751716 031776 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000151 12302131606 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java-deprecated/org/apache/http/impl/client/cache/httpcomponents-client-4.3.3/httpclient-cache/src/main/java-deprecated/org/apache/http/impl/client/ca0040755 0000000 0000000 00000000000 12301751716 032302 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000177 12302131606 011632 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/main/java-deprecated/org/apache/http/impl/client/cache/CachingHttpClient.javahttpcomponents-client-4.3.3/httpclient-cache/src/main/java-deprecated/org/apache/http/impl/client/ca0100644 0000000 0000000 00000137464 12301751716 032320 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import java.lang.reflect.UndeclaredThrowableException; import java.net.URI; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpMessage; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.ProtocolException; import org.apache.http.ProtocolVersion; import org.apache.http.RequestLine; import org.apache.http.annotation.ThreadSafe; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.cache.CacheResponseStatus; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.client.cache.ResourceFactory; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.cookie.DateParseException; import org.apache.http.impl.cookie.DateUtils; import org.apache.http.message.BasicHttpResponse; import org.apache.http.params.HttpParams; import org.apache.http.protocol.ExecutionContext; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import org.apache.http.util.VersionInfo; /** *

The {@link CachingHttpClient} is meant to be a drop-in replacement for * a {@link DefaultHttpClient} that transparently adds client-side caching. * The current implementation is conditionally compliant with HTTP/1.1 * (meaning all the MUST and MUST NOTs are obeyed), although quite a lot, * though not all, of the SHOULDs and SHOULD NOTs are obeyed too. Generally * speaking, you construct a {@code CachingHttpClient} by providing a * "backend" {@link HttpClient} used for making actual network requests and * provide an {@link HttpCacheStorage} instance to use for holding onto * cached responses. Additional configuration options can be provided by * passing in a {@link CacheConfig}. Note that all of the usual client * related configuration you want to do vis-a-vis timeouts and connection * pools should be done on this backend client before constructing a {@code * CachingHttpClient} from it.

* *

Generally speaking, the {@code CachingHttpClient} is implemented as a * Decorator * of the backend client; for any incoming request it attempts to satisfy * it from the cache, but if it can't, or if it needs to revalidate a stale * cache entry, it will use the backend client to make an actual request. * However, a proper HTTP/1.1 cache won't change the semantics of a request * and response; in particular, if you issue an unconditional request you * will get a full response (although it may be served to you from the cache, * or the cache may make a conditional request on your behalf to the origin). * This notion of "semantic transparency" means you should be able to drop * a {@link CachingHttpClient} into an existing application without breaking * anything.

* *

Folks that would like to experiment with alternative storage backends * should look at the {@link HttpCacheStorage} interface and the related * package documentation there. You may also be interested in the provided * {@link org.apache.http.impl.client.cache.ehcache.EhcacheHttpCacheStorage * EhCache} and {@link * org.apache.http.impl.client.cache.memcached.MemcachedHttpCacheStorage * memcached} storage backends.

*

* @since 4.1 * * @deprecated (4.3) use {@link CachingHttpClientBuilder} or {@link CachingHttpClients}. */ @Deprecated @ThreadSafe // So long as the responseCache implementation is threadsafe public class CachingHttpClient implements HttpClient { /** * This is the name under which the {@link * org.apache.http.client.cache.CacheResponseStatus} of a request * (for example, whether it resulted in a cache hit) will be recorded if an * {@link HttpContext} is provided during execution. */ public static final String CACHE_RESPONSE_STATUS = "http.cache.response.status"; private final static boolean SUPPORTS_RANGE_AND_CONTENT_RANGE_HEADERS = false; private final AtomicLong cacheHits = new AtomicLong(); private final AtomicLong cacheMisses = new AtomicLong(); private final AtomicLong cacheUpdates = new AtomicLong(); private final Map viaHeaders = new HashMap(4); private final HttpClient backend; private final HttpCache responseCache; private final CacheValidityPolicy validityPolicy; private final ResponseCachingPolicy responseCachingPolicy; private final CachedHttpResponseGenerator responseGenerator; private final CacheableRequestPolicy cacheableRequestPolicy; private final CachedResponseSuitabilityChecker suitabilityChecker; private final ConditionalRequestBuilder conditionalRequestBuilder; private final long maxObjectSizeBytes; private final boolean sharedCache; private final ResponseProtocolCompliance responseCompliance; private final RequestProtocolCompliance requestCompliance; private final AsynchronousValidator asynchRevalidator; private final Log log = LogFactory.getLog(getClass()); CachingHttpClient( final HttpClient client, final HttpCache cache, final CacheConfig config) { super(); Args.notNull(client, "HttpClient"); Args.notNull(cache, "HttpCache"); Args.notNull(config, "CacheConfig"); this.maxObjectSizeBytes = config.getMaxObjectSize(); this.sharedCache = config.isSharedCache(); this.backend = client; this.responseCache = cache; this.validityPolicy = new CacheValidityPolicy(); this.responseCachingPolicy = new ResponseCachingPolicy(maxObjectSizeBytes, sharedCache, config.isNeverCacheHTTP10ResponsesWithQuery(), config.is303CachingEnabled()); this.responseGenerator = new CachedHttpResponseGenerator(this.validityPolicy); this.cacheableRequestPolicy = new CacheableRequestPolicy(); this.suitabilityChecker = new CachedResponseSuitabilityChecker(this.validityPolicy, config); this.conditionalRequestBuilder = new ConditionalRequestBuilder(); this.responseCompliance = new ResponseProtocolCompliance(); this.requestCompliance = new RequestProtocolCompliance(config.isWeakETagOnPutDeleteAllowed()); this.asynchRevalidator = makeAsynchronousValidator(config); } /** * Constructs a {@code CachingHttpClient} with default caching settings that * stores cache entries in memory and uses a vanilla {@link DefaultHttpClient} * for backend requests. */ public CachingHttpClient() { this(new DefaultHttpClient(), new BasicHttpCache(), new CacheConfig()); } /** * Constructs a {@code CachingHttpClient} with the given caching options that * stores cache entries in memory and uses a vanilla {@link DefaultHttpClient} * for backend requests. * @param config cache module options */ public CachingHttpClient(final CacheConfig config) { this(new DefaultHttpClient(), new BasicHttpCache(config), config); } /** * Constructs a {@code CachingHttpClient} with default caching settings that * stores cache entries in memory and uses the given {@link HttpClient} * for backend requests. * @param client used to make origin requests */ public CachingHttpClient(final HttpClient client) { this(client, new BasicHttpCache(), new CacheConfig()); } /** * Constructs a {@code CachingHttpClient} with the given caching options that * stores cache entries in memory and uses the given {@link HttpClient} * for backend requests. * @param config cache module options * @param client used to make origin requests */ public CachingHttpClient(final HttpClient client, final CacheConfig config) { this(client, new BasicHttpCache(config), config); } /** * Constructs a {@code CachingHttpClient} with the given caching options * that stores cache entries in the provided storage backend and uses * the given {@link HttpClient} for backend requests. However, cached * response bodies are managed using the given {@link ResourceFactory}. * @param client used to make origin requests * @param resourceFactory how to manage cached response bodies * @param storage where to store cache entries * @param config cache module options */ public CachingHttpClient( final HttpClient client, final ResourceFactory resourceFactory, final HttpCacheStorage storage, final CacheConfig config) { this(client, new BasicHttpCache(resourceFactory, storage, config), config); } /** * Constructs a {@code CachingHttpClient} with the given caching options * that stores cache entries in the provided storage backend and uses * the given {@link HttpClient} for backend requests. * @param client used to make origin requests * @param storage where to store cache entries * @param config cache module options */ public CachingHttpClient( final HttpClient client, final HttpCacheStorage storage, final CacheConfig config) { this(client, new BasicHttpCache(new HeapResourceFactory(), storage, config), config); } CachingHttpClient( final HttpClient backend, final CacheValidityPolicy validityPolicy, final ResponseCachingPolicy responseCachingPolicy, final HttpCache responseCache, final CachedHttpResponseGenerator responseGenerator, final CacheableRequestPolicy cacheableRequestPolicy, final CachedResponseSuitabilityChecker suitabilityChecker, final ConditionalRequestBuilder conditionalRequestBuilder, final ResponseProtocolCompliance responseCompliance, final RequestProtocolCompliance requestCompliance) { final CacheConfig config = new CacheConfig(); this.maxObjectSizeBytes = config.getMaxObjectSize(); this.sharedCache = config.isSharedCache(); this.backend = backend; this.validityPolicy = validityPolicy; this.responseCachingPolicy = responseCachingPolicy; this.responseCache = responseCache; this.responseGenerator = responseGenerator; this.cacheableRequestPolicy = cacheableRequestPolicy; this.suitabilityChecker = suitabilityChecker; this.conditionalRequestBuilder = conditionalRequestBuilder; this.responseCompliance = responseCompliance; this.requestCompliance = requestCompliance; this.asynchRevalidator = makeAsynchronousValidator(config); } private AsynchronousValidator makeAsynchronousValidator( final CacheConfig config) { if (config.getAsynchronousWorkersMax() > 0) { return new AsynchronousValidator(this, config); } return null; } /** * Reports the number of times that the cache successfully responded * to an {@link HttpRequest} without contacting the origin server. * @return the number of cache hits */ public long getCacheHits() { return cacheHits.get(); } /** * Reports the number of times that the cache contacted the origin * server because it had no appropriate response cached. * @return the number of cache misses */ public long getCacheMisses() { return cacheMisses.get(); } /** * Reports the number of times that the cache was able to satisfy * a response by revalidating an existing but stale cache entry. * @return the number of cache revalidations */ public long getCacheUpdates() { return cacheUpdates.get(); } public HttpResponse execute(final HttpHost target, final HttpRequest request) throws IOException { final HttpContext defaultContext = null; return execute(target, request, defaultContext); } public T execute(final HttpHost target, final HttpRequest request, final ResponseHandler responseHandler) throws IOException { return execute(target, request, responseHandler, null); } public T execute(final HttpHost target, final HttpRequest request, final ResponseHandler responseHandler, final HttpContext context) throws IOException { final HttpResponse resp = execute(target, request, context); return handleAndConsume(responseHandler,resp); } public HttpResponse execute(final HttpUriRequest request) throws IOException { final HttpContext context = null; return execute(request, context); } public HttpResponse execute(final HttpUriRequest request, final HttpContext context) throws IOException { final URI uri = request.getURI(); final HttpHost httpHost = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme()); return execute(httpHost, request, context); } public T execute(final HttpUriRequest request, final ResponseHandler responseHandler) throws IOException { return execute(request, responseHandler, null); } public T execute(final HttpUriRequest request, final ResponseHandler responseHandler, final HttpContext context) throws IOException { final HttpResponse resp = execute(request, context); return handleAndConsume(responseHandler, resp); } private T handleAndConsume( final ResponseHandler responseHandler, final HttpResponse response) throws Error, IOException { T result; try { result = responseHandler.handleResponse(response); } catch (final Exception t) { final HttpEntity entity = response.getEntity(); try { IOUtils.consume(entity); } catch (final Exception t2) { // Log this exception. The original exception is more // important and will be thrown to the caller. this.log.warn("Error consuming content after an exception.", t2); } if (t instanceof RuntimeException) { throw (RuntimeException) t; } if (t instanceof IOException) { throw (IOException) t; } throw new UndeclaredThrowableException(t); } // Handling the response was successful. Ensure that the content has // been fully consumed. final HttpEntity entity = response.getEntity(); IOUtils.consume(entity); return result; } public ClientConnectionManager getConnectionManager() { return backend.getConnectionManager(); } public HttpParams getParams() { return backend.getParams(); } public HttpResponse execute(final HttpHost target, final HttpRequest originalRequest, final HttpContext context) throws IOException { HttpRequestWrapper request; if (originalRequest instanceof HttpRequestWrapper) { request = ((HttpRequestWrapper) originalRequest); } else { request = HttpRequestWrapper.wrap(originalRequest); } final String via = generateViaHeader(originalRequest); // default response context setResponseStatus(context, CacheResponseStatus.CACHE_MISS); if (clientRequestsOurOptions(request)) { setResponseStatus(context, CacheResponseStatus.CACHE_MODULE_RESPONSE); return new OptionsHttp11Response(); } final HttpResponse fatalErrorResponse = getFatallyNoncompliantResponse( request, context); if (fatalErrorResponse != null) { return fatalErrorResponse; } requestCompliance.makeRequestCompliant(request); request.addHeader("Via",via); flushEntriesInvalidatedByRequest(target, request); if (!cacheableRequestPolicy.isServableFromCache(request)) { log.debug("Request is not servable from cache"); return callBackend(target, request, context); } final HttpCacheEntry entry = satisfyFromCache(target, request); if (entry == null) { log.debug("Cache miss"); return handleCacheMiss(target, request, context); } return handleCacheHit(target, request, context, entry); } private HttpResponse handleCacheHit(final HttpHost target, final HttpRequestWrapper request, final HttpContext context, final HttpCacheEntry entry) throws ClientProtocolException, IOException { recordCacheHit(target, request); HttpResponse out = null; final Date now = getCurrentDate(); if (suitabilityChecker.canCachedResponseBeUsed(target, request, entry, now)) { log.debug("Cache hit"); out = generateCachedResponse(request, context, entry, now); } else if (!mayCallBackend(request)) { log.debug("Cache entry not suitable but only-if-cached requested"); out = generateGatewayTimeout(context); } else { log.debug("Revalidating cache entry"); return revalidateCacheEntry(target, request, context, entry, now); } if (context != null) { context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target); context.setAttribute(ExecutionContext.HTTP_REQUEST, request); context.setAttribute(ExecutionContext.HTTP_RESPONSE, out); context.setAttribute(ExecutionContext.HTTP_REQ_SENT, Boolean.TRUE); } return out; } private HttpResponse revalidateCacheEntry(final HttpHost target, final HttpRequestWrapper request, final HttpContext context, final HttpCacheEntry entry, final Date now) throws ClientProtocolException { try { if (asynchRevalidator != null && !staleResponseNotAllowed(request, entry, now) && validityPolicy.mayReturnStaleWhileRevalidating(entry, now)) { log.trace("Serving stale with asynchronous revalidation"); final HttpResponse resp = generateCachedResponse(request, context, entry, now); asynchRevalidator.revalidateCacheEntry(target, request, context, entry); return resp; } return revalidateCacheEntry(target, request, context, entry); } catch (final IOException ioex) { return handleRevalidationFailure(request, context, entry, now); } catch (final ProtocolException e) { throw new ClientProtocolException(e); } } private HttpResponse handleCacheMiss(final HttpHost target, final HttpRequestWrapper request, final HttpContext context) throws IOException { recordCacheMiss(target, request); if (!mayCallBackend(request)) { return new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout"); } final Map variants = getExistingCacheVariants(target, request); if (variants != null && variants.size() > 0) { return negotiateResponseFromVariants(target, request, context, variants); } return callBackend(target, request, context); } private HttpCacheEntry satisfyFromCache(final HttpHost target, final HttpRequestWrapper request) { HttpCacheEntry entry = null; try { entry = responseCache.getCacheEntry(target, request); } catch (final IOException ioe) { log.warn("Unable to retrieve entries from cache", ioe); } return entry; } private HttpResponse getFatallyNoncompliantResponse(final HttpRequestWrapper request, final HttpContext context) { HttpResponse fatalErrorResponse = null; final List fatalError = requestCompliance.requestIsFatallyNonCompliant(request); for (final RequestProtocolError error : fatalError) { setResponseStatus(context, CacheResponseStatus.CACHE_MODULE_RESPONSE); fatalErrorResponse = requestCompliance.getErrorForRequest(error); } return fatalErrorResponse; } private Map getExistingCacheVariants(final HttpHost target, final HttpRequestWrapper request) { Map variants = null; try { variants = responseCache.getVariantCacheEntriesWithEtags(target, request); } catch (final IOException ioe) { log.warn("Unable to retrieve variant entries from cache", ioe); } return variants; } private void recordCacheMiss(final HttpHost target, final HttpRequestWrapper request) { cacheMisses.getAndIncrement(); if (log.isTraceEnabled()) { final RequestLine rl = request.getRequestLine(); log.trace("Cache miss [host: " + target + "; uri: " + rl.getUri() + "]"); } } private void recordCacheHit(final HttpHost target, final HttpRequestWrapper request) { cacheHits.getAndIncrement(); if (log.isTraceEnabled()) { final RequestLine rl = request.getRequestLine(); log.trace("Cache hit [host: " + target + "; uri: " + rl.getUri() + "]"); } } private void recordCacheUpdate(final HttpContext context) { cacheUpdates.getAndIncrement(); setResponseStatus(context, CacheResponseStatus.VALIDATED); } private void flushEntriesInvalidatedByRequest(final HttpHost target, final HttpRequestWrapper request) { try { responseCache.flushInvalidatedCacheEntriesFor(target, request); } catch (final IOException ioe) { log.warn("Unable to flush invalidated entries from cache", ioe); } } private HttpResponse generateCachedResponse(final HttpRequestWrapper request, final HttpContext context, final HttpCacheEntry entry, final Date now) { final HttpResponse cachedResponse; if (request.containsHeader(HeaderConstants.IF_NONE_MATCH) || request.containsHeader(HeaderConstants.IF_MODIFIED_SINCE)) { cachedResponse = responseGenerator.generateNotModifiedResponse(entry); } else { cachedResponse = responseGenerator.generateResponse(entry); } setResponseStatus(context, CacheResponseStatus.CACHE_HIT); if (validityPolicy.getStalenessSecs(entry, now) > 0L) { cachedResponse.addHeader(HeaderConstants.WARNING,"110 localhost \"Response is stale\""); } return cachedResponse; } private HttpResponse handleRevalidationFailure(final HttpRequestWrapper request, final HttpContext context, final HttpCacheEntry entry, final Date now) { if (staleResponseNotAllowed(request, entry, now)) { return generateGatewayTimeout(context); } else { return unvalidatedCacheHit(context, entry); } } private HttpResponse generateGatewayTimeout(final HttpContext context) { setResponseStatus(context, CacheResponseStatus.CACHE_MODULE_RESPONSE); return new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout"); } private HttpResponse unvalidatedCacheHit(final HttpContext context, final HttpCacheEntry entry) { final HttpResponse cachedResponse = responseGenerator.generateResponse(entry); setResponseStatus(context, CacheResponseStatus.CACHE_HIT); cachedResponse.addHeader(HeaderConstants.WARNING, "111 localhost \"Revalidation failed\""); return cachedResponse; } private boolean staleResponseNotAllowed(final HttpRequestWrapper request, final HttpCacheEntry entry, final Date now) { return validityPolicy.mustRevalidate(entry) || (isSharedCache() && validityPolicy.proxyRevalidate(entry)) || explicitFreshnessRequest(request, entry, now); } private boolean mayCallBackend(final HttpRequestWrapper request) { for (final Header h: request.getHeaders(HeaderConstants.CACHE_CONTROL)) { for (final HeaderElement elt : h.getElements()) { if ("only-if-cached".equals(elt.getName())) { log.trace("Request marked only-if-cached"); return false; } } } return true; } private boolean explicitFreshnessRequest(final HttpRequestWrapper request, final HttpCacheEntry entry, final Date now) { for(final Header h : request.getHeaders(HeaderConstants.CACHE_CONTROL)) { for(final HeaderElement elt : h.getElements()) { if (HeaderConstants.CACHE_CONTROL_MAX_STALE.equals(elt.getName())) { try { final int maxstale = Integer.parseInt(elt.getValue()); final long age = validityPolicy.getCurrentAgeSecs(entry, now); final long lifetime = validityPolicy.getFreshnessLifetimeSecs(entry); if (age - lifetime > maxstale) { return true; } } catch (final NumberFormatException nfe) { return true; } } else if (HeaderConstants.CACHE_CONTROL_MIN_FRESH.equals(elt.getName()) || HeaderConstants.CACHE_CONTROL_MAX_AGE.equals(elt.getName())) { return true; } } } return false; } private String generateViaHeader(final HttpMessage msg) { final ProtocolVersion pv = msg.getProtocolVersion(); final String existingEntry = viaHeaders.get(pv); if (existingEntry != null) { return existingEntry; } final VersionInfo vi = VersionInfo.loadVersionInfo("org.apache.http.client", getClass().getClassLoader()); final String release = (vi != null) ? vi.getRelease() : VersionInfo.UNAVAILABLE; String value; if ("http".equalsIgnoreCase(pv.getProtocol())) { value = String.format("%d.%d localhost (Apache-HttpClient/%s (cache))", pv.getMajor(), pv.getMinor(), release); } else { value = String.format("%s/%d.%d localhost (Apache-HttpClient/%s (cache))", pv.getProtocol(), pv.getMajor(), pv.getMinor(), release); } viaHeaders.put(pv, value); return value; } private void setResponseStatus(final HttpContext context, final CacheResponseStatus value) { if (context != null) { context.setAttribute(CACHE_RESPONSE_STATUS, value); } } /** * Reports whether this {@code CachingHttpClient} implementation * supports byte-range requests as specified by the {@code Range} * and {@code Content-Range} headers. * @return {@code true} if byte-range requests are supported */ public boolean supportsRangeAndContentRangeHeaders() { return SUPPORTS_RANGE_AND_CONTENT_RANGE_HEADERS; } /** * Reports whether this {@code CachingHttpClient} is configured as * a shared (public) or non-shared (private) cache. See {@link * CacheConfig#setSharedCache(boolean)}. * @return {@code true} if we are behaving as a shared (public) * cache */ public boolean isSharedCache() { return sharedCache; } Date getCurrentDate() { return new Date(); } boolean clientRequestsOurOptions(final HttpRequest request) { final RequestLine line = request.getRequestLine(); if (!HeaderConstants.OPTIONS_METHOD.equals(line.getMethod())) { return false; } if (!"*".equals(line.getUri())) { return false; } if (!"0".equals(request.getFirstHeader(HeaderConstants.MAX_FORWARDS).getValue())) { return false; } return true; } HttpResponse callBackend(final HttpHost target, final HttpRequestWrapper request, final HttpContext context) throws IOException { final Date requestDate = getCurrentDate(); log.trace("Calling the backend"); final HttpResponse backendResponse = backend.execute(target, request, context); backendResponse.addHeader("Via", generateViaHeader(backendResponse)); return handleBackendResponse(target, request, requestDate, getCurrentDate(), backendResponse); } private boolean revalidationResponseIsTooOld(final HttpResponse backendResponse, final HttpCacheEntry cacheEntry) { final Header entryDateHeader = cacheEntry.getFirstHeader(HTTP.DATE_HEADER); final Header responseDateHeader = backendResponse.getFirstHeader(HTTP.DATE_HEADER); if (entryDateHeader != null && responseDateHeader != null) { try { final Date entryDate = DateUtils.parseDate(entryDateHeader.getValue()); final Date respDate = DateUtils.parseDate(responseDateHeader.getValue()); if (respDate.before(entryDate)) { return true; } } catch (final DateParseException e) { // either backend response or cached entry did not have a valid // Date header, so we can't tell if they are out of order // according to the origin clock; thus we can skip the // unconditional retry recommended in 13.2.6 of RFC 2616. } } return false; } HttpResponse negotiateResponseFromVariants(final HttpHost target, final HttpRequestWrapper request, final HttpContext context, final Map variants) throws IOException { final HttpRequestWrapper conditionalRequest = conditionalRequestBuilder .buildConditionalRequestFromVariants(request, variants); final Date requestDate = getCurrentDate(); final HttpResponse backendResponse = backend.execute(target, conditionalRequest, context); final Date responseDate = getCurrentDate(); backendResponse.addHeader("Via", generateViaHeader(backendResponse)); if (backendResponse.getStatusLine().getStatusCode() != HttpStatus.SC_NOT_MODIFIED) { return handleBackendResponse(target, request, requestDate, responseDate, backendResponse); } final Header resultEtagHeader = backendResponse.getFirstHeader(HeaderConstants.ETAG); if (resultEtagHeader == null) { log.warn("304 response did not contain ETag"); return callBackend(target, request, context); } final String resultEtag = resultEtagHeader.getValue(); final Variant matchingVariant = variants.get(resultEtag); if (matchingVariant == null) { log.debug("304 response did not contain ETag matching one sent in If-None-Match"); return callBackend(target, request, context); } final HttpCacheEntry matchedEntry = matchingVariant.getEntry(); if (revalidationResponseIsTooOld(backendResponse, matchedEntry)) { IOUtils.consume(backendResponse.getEntity()); return retryRequestUnconditionally(target, request, context, matchedEntry); } recordCacheUpdate(context); final HttpCacheEntry responseEntry = getUpdatedVariantEntry(target, conditionalRequest, requestDate, responseDate, backendResponse, matchingVariant, matchedEntry); final HttpResponse resp = responseGenerator.generateResponse(responseEntry); tryToUpdateVariantMap(target, request, matchingVariant); if (shouldSendNotModifiedResponse(request, responseEntry)) { return responseGenerator.generateNotModifiedResponse(responseEntry); } return resp; } private HttpResponse retryRequestUnconditionally(final HttpHost target, final HttpRequestWrapper request, final HttpContext context, final HttpCacheEntry matchedEntry) throws IOException { final HttpRequestWrapper unconditional = conditionalRequestBuilder .buildUnconditionalRequest(request, matchedEntry); return callBackend(target, unconditional, context); } private HttpCacheEntry getUpdatedVariantEntry(final HttpHost target, final HttpRequestWrapper conditionalRequest, final Date requestDate, final Date responseDate, final HttpResponse backendResponse, final Variant matchingVariant, final HttpCacheEntry matchedEntry) { HttpCacheEntry responseEntry = matchedEntry; try { responseEntry = responseCache.updateVariantCacheEntry(target, conditionalRequest, matchedEntry, backendResponse, requestDate, responseDate, matchingVariant.getCacheKey()); } catch (final IOException ioe) { log.warn("Could not update cache entry", ioe); } return responseEntry; } private void tryToUpdateVariantMap(final HttpHost target, final HttpRequestWrapper request, final Variant matchingVariant) { try { responseCache.reuseVariantEntryFor(target, request, matchingVariant); } catch (final IOException ioe) { log.warn("Could not update cache entry to reuse variant", ioe); } } private boolean shouldSendNotModifiedResponse(final HttpRequestWrapper request, final HttpCacheEntry responseEntry) { return (suitabilityChecker.isConditional(request) && suitabilityChecker.allConditionalsMatch(request, responseEntry, new Date())); } HttpResponse revalidateCacheEntry( final HttpHost target, final HttpRequestWrapper request, final HttpContext context, final HttpCacheEntry cacheEntry) throws IOException, ProtocolException { final HttpRequestWrapper conditionalRequest = conditionalRequestBuilder.buildConditionalRequest(request, cacheEntry); Date requestDate = getCurrentDate(); HttpResponse backendResponse = backend.execute(target, conditionalRequest, context); Date responseDate = getCurrentDate(); if (revalidationResponseIsTooOld(backendResponse, cacheEntry)) { IOUtils.consume(backendResponse.getEntity()); final HttpRequest unconditional = conditionalRequestBuilder .buildUnconditionalRequest(request, cacheEntry); requestDate = getCurrentDate(); backendResponse = backend.execute(target, unconditional, context); responseDate = getCurrentDate(); } backendResponse.addHeader(HeaderConstants.VIA, generateViaHeader(backendResponse)); final int statusCode = backendResponse.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_NOT_MODIFIED || statusCode == HttpStatus.SC_OK) { recordCacheUpdate(context); } if (statusCode == HttpStatus.SC_NOT_MODIFIED) { final HttpCacheEntry updatedEntry = responseCache.updateCacheEntry(target, request, cacheEntry, backendResponse, requestDate, responseDate); if (suitabilityChecker.isConditional(request) && suitabilityChecker.allConditionalsMatch(request, updatedEntry, new Date())) { return responseGenerator.generateNotModifiedResponse(updatedEntry); } return responseGenerator.generateResponse(updatedEntry); } if (staleIfErrorAppliesTo(statusCode) && !staleResponseNotAllowed(request, cacheEntry, getCurrentDate()) && validityPolicy.mayReturnStaleIfError(request, cacheEntry, responseDate)) { final HttpResponse cachedResponse = responseGenerator.generateResponse(cacheEntry); cachedResponse.addHeader(HeaderConstants.WARNING, "110 localhost \"Response is stale\""); final HttpEntity errorBody = backendResponse.getEntity(); if (errorBody != null) { IOUtils.consume(errorBody); } return cachedResponse; } return handleBackendResponse(target, conditionalRequest, requestDate, responseDate, backendResponse); } private boolean staleIfErrorAppliesTo(final int statusCode) { return statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR || statusCode == HttpStatus.SC_BAD_GATEWAY || statusCode == HttpStatus.SC_SERVICE_UNAVAILABLE || statusCode == HttpStatus.SC_GATEWAY_TIMEOUT; } HttpResponse handleBackendResponse( final HttpHost target, final HttpRequestWrapper request, final Date requestDate, final Date responseDate, final HttpResponse backendResponse) throws IOException { log.trace("Handling Backend response"); responseCompliance.ensureProtocolCompliance(request, backendResponse); final boolean cacheable = responseCachingPolicy.isResponseCacheable(request, backendResponse); responseCache.flushInvalidatedCacheEntriesFor(target, request, backendResponse); if (cacheable && !alreadyHaveNewerCacheEntry(target, request, backendResponse)) { try { storeRequestIfModifiedSinceFor304Response(request, backendResponse); return responseCache.cacheAndReturnResponse(target, request, backendResponse, requestDate, responseDate); } catch (final IOException ioe) { log.warn("Unable to store entries in cache", ioe); } } if (!cacheable) { try { responseCache.flushCacheEntriesFor(target, request); } catch (final IOException ioe) { log.warn("Unable to flush invalid cache entries", ioe); } } return backendResponse; } /** * For 304 Not modified responses, adds a "Last-Modified" header with the * value of the "If-Modified-Since" header passed in the request. This * header is required to be able to reuse match the cache entry for * subsequent requests but as defined in http specifications it is not * included in 304 responses by backend servers. This header will not be * included in the resulting response. */ private void storeRequestIfModifiedSinceFor304Response( final HttpRequest request, final HttpResponse backendResponse) { if (backendResponse.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_MODIFIED) { final Header h = request.getFirstHeader("If-Modified-Since"); if (h != null) { backendResponse.addHeader("Last-Modified", h.getValue()); } } } private boolean alreadyHaveNewerCacheEntry(final HttpHost target, final HttpRequest request, final HttpResponse backendResponse) { HttpCacheEntry existing = null; try { existing = responseCache.getCacheEntry(target, request); } catch (final IOException ioe) { // nop } if (existing == null) { return false; } final Header entryDateHeader = existing.getFirstHeader(HTTP.DATE_HEADER); if (entryDateHeader == null) { return false; } final Header responseDateHeader = backendResponse.getFirstHeader(HTTP.DATE_HEADER); if (responseDateHeader == null) { return false; } try { final Date entryDate = DateUtils.parseDate(entryDateHeader.getValue()); final Date responseDate = DateUtils.parseDate(responseDateHeader.getValue()); return responseDate.before(entryDate); } catch (final DateParseException e) { // Empty on Purpose } return false; } static class AsynchronousValidator { private final CachingHttpClient cachingClient; private final ExecutorService executor; private final Set queued; private final CacheKeyGenerator cacheKeyGenerator; private final Log log = LogFactory.getLog(getClass()); /** * Create AsynchronousValidator which will make revalidation requests * using the supplied {@link CachingHttpClient}, and * a {@link ThreadPoolExecutor} generated according to the thread * pool settings provided in the given {@link CacheConfig}. * @param cachingClient used to execute asynchronous requests * @param config specifies thread pool settings. See * {@link CacheConfig#getAsynchronousWorkersMax()}, * {@link CacheConfig#getAsynchronousWorkersCore()}, * {@link CacheConfig#getAsynchronousWorkerIdleLifetimeSecs()}, * and {@link CacheConfig#getRevalidationQueueSize()}. */ public AsynchronousValidator(final CachingHttpClient cachingClient, final CacheConfig config) { this(cachingClient, new ThreadPoolExecutor(config.getAsynchronousWorkersCore(), config.getAsynchronousWorkersMax(), config.getAsynchronousWorkerIdleLifetimeSecs(), TimeUnit.SECONDS, new ArrayBlockingQueue(config.getRevalidationQueueSize())) ); } /** * Create AsynchronousValidator which will make revalidation requests * using the supplied {@link CachingHttpClient} and * {@link ExecutorService}. * @param cachingClient used to execute asynchronous requests * @param executor used to manage a thread pool of revalidation workers */ AsynchronousValidator(final CachingHttpClient cachingClient, final ExecutorService executor) { this.cachingClient = cachingClient; this.executor = executor; this.queued = new HashSet(); this.cacheKeyGenerator = new CacheKeyGenerator(); } /** * Schedules an asynchronous revalidation * * @param target * @param request * @param context * @param entry */ public synchronized void revalidateCacheEntry(final HttpHost target, final HttpRequestWrapper request, final HttpContext context, final HttpCacheEntry entry) { // getVariantURI will fall back on getURI if no variants exist final String uri = cacheKeyGenerator.getVariantURI(target, request, entry); if (!queued.contains(uri)) { final AsynchronousValidationRequest revalidationRequest = new AsynchronousValidationRequest(this, cachingClient, target, request, context, entry, uri); try { executor.execute(revalidationRequest); queued.add(uri); } catch (final RejectedExecutionException ree) { log.debug("Revalidation for [" + uri + "] not scheduled: " + ree); } } } /** * Removes an identifier from the internal list of revalidation jobs in * progress. This is meant to be called by * {@link AsynchronousValidationRequest#run()} once the revalidation is * complete, using the identifier passed in during constructions. * @param identifier */ synchronized void markComplete(final String identifier) { queued.remove(identifier); } Set getScheduledIdentifiers() { return Collections.unmodifiableSet(queued); } ExecutorService getExecutor() { return executor; } } static class AsynchronousValidationRequest implements Runnable { private final AsynchronousValidator parent; private final CachingHttpClient cachingClient; private final HttpHost target; private final HttpRequestWrapper request; private final HttpContext context; private final HttpCacheEntry cacheEntry; private final String identifier; private final Log log = LogFactory.getLog(getClass()); /** * Used internally by {@link AsynchronousValidator} to schedule a * revalidation. * @param cachingClient * @param target * @param request * @param context * @param cacheEntry * @param bookKeeping * @param identifier */ AsynchronousValidationRequest(final AsynchronousValidator parent, final CachingHttpClient cachingClient, final HttpHost target, final HttpRequestWrapper request, final HttpContext context, final HttpCacheEntry cacheEntry, final String identifier) { this.parent = parent; this.cachingClient = cachingClient; this.target = target; this.request = request; this.context = context; this.cacheEntry = cacheEntry; this.identifier = identifier; } public void run() { try { cachingClient.revalidateCacheEntry(target, request, context, cacheEntry); } catch (final IOException ioe) { log.debug("Asynchronous revalidation failed due to exception: " + ioe); } catch (final ProtocolException pe) { log.error("ProtocolException thrown during asynchronous revalidation: " + pe); } finally { parent.markComplete(identifier); } } String getIdentifier() { return identifier; } } } httpcomponents-client-4.3.3/httpclient-cache/src/test/0040755 0000000 0000000 00000000000 12301751716 021604 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/0040755 0000000 0000000 00000000000 12301751712 022521 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/0040755 0000000 0000000 00000000000 12301751712 023310 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/0040755 0000000 0000000 00000000000 12301751712 024531 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/0040755 0000000 0000000 00000000000 12301751712 025510 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/client/0040755 0000000 0000000 00000000000 12301751712 026766 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/client/cache/0040755 0000000 0000000 00000000000 12301751712 030031 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000160 12302131606 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCach0100644 0000000 0000000 00000027423 12301751712 032317 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.client.cache; import static org.easymock.classextension.EasyMock.createNiceMock; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.http.Header; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.StatusLine; import org.apache.http.client.utils.DateUtils; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicStatusLine; import org.junit.Before; import org.junit.Test; public class TestHttpCacheEntry { private Date now; private Date elevenSecondsAgo; private Date nineSecondsAgo; private Resource mockResource; private StatusLine statusLine; private HttpCacheEntry entry; @Before public void setUp() { now = new Date(); elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L); nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); mockResource = createNiceMock(Resource.class); } private HttpCacheEntry makeEntry(final Header[] headers) { return new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, statusLine, headers, mockResource); } @Test public void testGetHeadersReturnsCorrectHeaders() { final Header[] headers = { new BasicHeader("foo", "fooValue"), new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") }; entry = makeEntry(headers); assertEquals(2, entry.getHeaders("bar").length); } @Test public void testGetFirstHeaderReturnsCorrectHeader() { final Header[] headers = { new BasicHeader("foo", "fooValue"), new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") }; entry = makeEntry(headers); assertEquals("barValue1", entry.getFirstHeader("bar").getValue()); } @Test public void testGetHeadersReturnsEmptyArrayIfNoneMatch() { final Header[] headers = { new BasicHeader("foo", "fooValue"), new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") }; entry = makeEntry(headers); assertEquals(0, entry.getHeaders("baz").length); } @Test public void testGetFirstHeaderReturnsNullIfNoneMatch() { final Header[] headers = { new BasicHeader("foo", "fooValue"), new BasicHeader("bar", "barValue1"), new BasicHeader("bar", "barValue2") }; entry = makeEntry(headers); assertEquals(null, entry.getFirstHeader("quux")); } @Test public void testCacheEntryWithNoVaryHeaderDoesNotHaveVariants() { final Header[] headers = new Header[0]; entry = makeEntry(headers); assertFalse(entry.hasVariants()); } @Test public void testCacheEntryWithOneVaryHeaderHasVariants() { final Header[] headers = { new BasicHeader("Vary", "User-Agent") }; entry = makeEntry(headers); assertTrue(entry.hasVariants()); } @Test public void testCacheEntryWithMultipleVaryHeadersHasVariants() { final Header[] headers = { new BasicHeader("Vary", "User-Agent"), new BasicHeader("Vary", "Accept-Encoding") }; entry = makeEntry(headers); assertTrue(entry.hasVariants()); } @Test public void testCacheEntryWithVaryStarHasVariants(){ final Header[] headers = { new BasicHeader("Vary", "*") }; entry = makeEntry(headers); assertTrue(entry.hasVariants()); } @Test public void mustProvideRequestDate() { try { new HttpCacheEntry(null, new Date(), statusLine, new Header[]{}, mockResource); fail("Should have thrown exception"); } catch (final IllegalArgumentException expected) { } } @Test public void mustProvideResponseDate() { try { new HttpCacheEntry(new Date(), null, statusLine, new Header[]{}, mockResource); fail("Should have thrown exception"); } catch (final IllegalArgumentException expected) { } } @Test public void mustProvideStatusLine() { try { new HttpCacheEntry(new Date(), new Date(), null, new Header[]{}, mockResource); fail("Should have thrown exception"); } catch (final IllegalArgumentException expected) { } } @Test public void mustProvideResponseHeaders() { try { new HttpCacheEntry(new Date(), new Date(), statusLine, null, mockResource); fail("Should have thrown exception"); } catch (final IllegalArgumentException expected) { } } @Test public void canRetrieveOriginalStatusLine() { entry = new HttpCacheEntry(new Date(), new Date(), statusLine, new Header[]{}, mockResource); assertSame(statusLine, entry.getStatusLine()); } @Test public void protocolVersionComesFromOriginalStatusLine() { entry = new HttpCacheEntry(new Date(), new Date(), statusLine, new Header[]{}, mockResource); assertSame(statusLine.getProtocolVersion(), entry.getProtocolVersion()); } @Test public void reasonPhraseComesFromOriginalStatusLine() { entry = new HttpCacheEntry(new Date(), new Date(), statusLine, new Header[]{}, mockResource); assertSame(statusLine.getReasonPhrase(), entry.getReasonPhrase()); } @Test public void statusCodeComesFromOriginalStatusLine() { entry = new HttpCacheEntry(new Date(), new Date(), statusLine, new Header[]{}, mockResource); assertEquals(statusLine.getStatusCode(), entry.getStatusCode()); } @Test public void canGetOriginalRequestDate() { final Date requestDate = new Date(); entry = new HttpCacheEntry(requestDate, new Date(), statusLine, new Header[]{}, mockResource); assertSame(requestDate, entry.getRequestDate()); } @Test public void canGetOriginalResponseDate() { final Date responseDate = new Date(); entry = new HttpCacheEntry(new Date(), responseDate, statusLine, new Header[]{}, mockResource); assertSame(responseDate, entry.getResponseDate()); } @Test public void canGetOriginalResource() { entry = new HttpCacheEntry(new Date(), new Date(), statusLine, new Header[]{}, mockResource); assertSame(mockResource, entry.getResource()); } @Test public void canGetOriginalHeaders() { final Header[] headers = { new BasicHeader("Server", "MockServer/1.0"), new BasicHeader("Date", DateUtils.formatDate(now)) }; entry = new HttpCacheEntry(new Date(), new Date(), statusLine, headers, mockResource); final Header[] result = entry.getAllHeaders(); assertEquals(headers.length, result.length); for(int i=0; i()); } @Test public void canRetrieveOriginalVariantMap() { final Map variantMap = new HashMap(); variantMap.put("A","B"); variantMap.put("C","D"); entry = new HttpCacheEntry(new Date(), new Date(), statusLine, new Header[]{}, mockResource, variantMap); final Map result = entry.getVariantMap(); assertEquals(2, result.size()); assertEquals("B", result.get("A")); assertEquals("D", result.get("C")); } @Test public void retrievedVariantMapIsNotModifiable() { final Map variantMap = new HashMap(); variantMap.put("A","B"); variantMap.put("C","D"); entry = new HttpCacheEntry(new Date(), new Date(), statusLine, new Header[]{}, mockResource, variantMap); final Map result = entry.getVariantMap(); try { result.remove("A"); fail("Should have thrown exception"); } catch (final UnsupportedOperationException expected) { } try { result.put("E","F"); fail("Should have thrown exception"); } catch (final UnsupportedOperationException expected) { } } @Test public void canConvertToString() { entry = new HttpCacheEntry(new Date(), new Date(), statusLine, new Header[]{}, mockResource); assertNotNull(entry.toString()); assertFalse("".equals(entry.toString())); } @Test public void testMissingDateHeaderIsIgnored() { final Header[] headers = new Header[] {}; entry = new HttpCacheEntry(new Date(), new Date(), statusLine, headers, mockResource); assertNull(entry.getDate()); } @Test public void testMalformedDateHeaderIsIgnored() { final Header[] headers = new Header[] { new BasicHeader("Date", "asdf") }; entry = new HttpCacheEntry(new Date(), new Date(), statusLine, headers, mockResource); assertNull(entry.getDate()); } @Test public void testValidDateHeaderIsParsed() { final long now = System.currentTimeMillis(); // round down to nearest second to make comparison easier final Date date = new Date(now - (now % 1000L)); final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(date)) }; entry = new HttpCacheEntry(new Date(), new Date(), statusLine, headers, mockResource); final Date dateHeaderValue = entry.getDate(); assertNotNull(dateHeaderValue); assertEquals(date.getTime(), dateHeaderValue.getTime()); } } httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/0040755 0000000 0000000 00000000000 12301751712 026451 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/0040755 0000000 0000000 00000000000 12301751712 027727 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/0040755 0000000 0000000 00000000000 12301751716 030776 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000167 12302131606 011631 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/AbstractProtocolTest.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/Abstrac0100644 0000000 0000000 00000015765 12301751716 032313 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.HashMap; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.cache.HttpCacheContext; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.impl.execchain.ClientExecChain; import org.apache.http.message.BasicHttpRequest; import org.easymock.IExpectationSetters; import org.easymock.classextension.EasyMock; import org.junit.Before; public abstract class AbstractProtocolTest { protected static final int MAX_BYTES = 1024; protected static final int MAX_ENTRIES = 100; protected int entityLength = 128; protected HttpHost host; protected HttpRoute route; protected HttpEntity body; protected ClientExecChain mockBackend; protected HttpCache mockCache; protected HttpRequestWrapper request; protected HttpCacheContext context; protected CloseableHttpResponse originResponse; protected CacheConfig config; protected ClientExecChain impl; protected HttpCache cache; public static HttpRequestWrapper eqRequest(final HttpRequestWrapper in) { EasyMock.reportMatcher(new RequestEquivalent(in)); return null; } public static HttpResponse eqResponse(final HttpResponse in) { EasyMock.reportMatcher(new ResponseEquivalent(in)); return null; } public static CloseableHttpResponse eqCloseableResponse(final CloseableHttpResponse in) { EasyMock.reportMatcher(new ResponseEquivalent(in)); return null; } @Before public void setUp() { host = new HttpHost("foo.example.com"); route = new HttpRoute(host); body = HttpTestUtils.makeBody(entityLength); request = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1)); context = HttpCacheContext.create(); context.setTargetHost(host); originResponse = Proxies.enhanceResponse(HttpTestUtils.make200Response()); config = CacheConfig.custom() .setMaxCacheEntries(MAX_ENTRIES) .setMaxObjectSize(MAX_BYTES) .build(); cache = new BasicHttpCache(config); mockBackend = EasyMock.createNiceMock(ClientExecChain.class); mockCache = EasyMock.createNiceMock(HttpCache.class); impl = createCachingExecChain(mockBackend, cache, config); } protected ClientExecChain createCachingExecChain(final ClientExecChain backend, final HttpCache cache, final CacheConfig config) { return new CachingExec(backend, cache, config); } protected boolean supportsRangeAndContentRangeHeaders(final ClientExecChain impl) { return impl instanceof CachingExec && ((CachingExec) impl).supportsRangeAndContentRangeHeaders(); } protected void replayMocks() { EasyMock.replay(mockBackend); EasyMock.replay(mockCache); } protected void verifyMocks() { EasyMock.verify(mockBackend); EasyMock.verify(mockCache); } protected IExpectationSetters backendExpectsAnyRequest() throws Exception { final CloseableHttpResponse resp = mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull()); return EasyMock.expect(resp); } protected IExpectationSetters backendExpectsAnyRequestAndReturn( final HttpResponse reponse) throws Exception { final CloseableHttpResponse resp = mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull()); return EasyMock.expect(resp).andReturn(Proxies.enhanceResponse(reponse)); } protected void emptyMockCacheExpectsNoPuts() throws Exception { mockBackend = EasyMock.createNiceMock(ClientExecChain.class); mockCache = EasyMock.createNiceMock(HttpCache.class); impl = new CachingExec(mockBackend, mockCache, config); EasyMock.expect(mockCache.getCacheEntry(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class))) .andReturn(null).anyTimes(); EasyMock.expect(mockCache.getVariantCacheEntriesWithEtags(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class))) .andReturn(new HashMap()).anyTimes(); mockCache.flushCacheEntriesFor(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)); EasyMock.expectLastCall().anyTimes(); mockCache.flushCacheEntriesFor(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)); EasyMock.expectLastCall().anyTimes(); mockCache.flushInvalidatedCacheEntriesFor(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)); EasyMock.expectLastCall().anyTimes(); mockCache.flushInvalidatedCacheEntriesFor(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class), EasyMock.isA(HttpResponse.class)); EasyMock.expectLastCall().anyTimes(); } protected void behaveAsNonSharedCache() { config = CacheConfig.custom() .setMaxCacheEntries(MAX_ENTRIES) .setMaxObjectSize(MAX_BYTES) .setSharedCache(false) .build(); impl = new CachingExec(mockBackend, cache, config); } public AbstractProtocolTest() { super(); } } ././@LongLink0100644 0000000 0000000 00000000170 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ConsumableInputStream.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/Consuma0100644 0000000 0000000 00000003521 12301751716 032324 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; public class ConsumableInputStream extends InputStream { private final ByteArrayInputStream buf; private boolean closed = false; public ConsumableInputStream(final ByteArrayInputStream buf) { this.buf = buf; } @Override public int read() throws IOException { return buf.read(); } @Override public void close() { closed = true; try { buf.close(); } catch (final IOException e) { } } public boolean wasClosed() { return closed; } } ././@LongLink0100644 0000000 0000000 00000000152 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/Counter.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/Counter0100644 0000000 0000000 00000002550 12301751715 032336 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; public class Counter { private int count; public void incr() { count++; } public int getCount() { return count; } } ././@LongLink0100644 0000000 0000000 00000000157 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/DummyBackend.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/DummyBa0100644 0000000 0000000 00000005156 12301751715 032262 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.ProtocolVersion; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.impl.execchain.ClientExecChain; import org.apache.http.message.BasicHttpResponse; public class DummyBackend implements ClientExecChain { private HttpRequest request; private HttpResponse response = new BasicHttpResponse(new ProtocolVersion("HTTP",1,1), HttpStatus.SC_OK, "OK"); private int executions = 0; public void setResponse(final HttpResponse resp) { response = resp; } public HttpRequest getCapturedRequest() { return request; } public CloseableHttpResponse execute( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext clientContext, final HttpExecutionAware execAware) throws IOException, HttpException { this.request = request; executions++; return Proxies.enhanceResponse(response); } public int getExecutions() { return executions; } } ././@LongLink0100644 0000000 0000000 00000000160 12302131606 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/HttpTestUtils.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/HttpTes0100644 0000000 0000000 00000034437 12301751714 032322 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.InputStream; import java.util.Date; import java.util.Map; import java.util.Random; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpEntity; import org.apache.http.HttpMessage; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.RequestLine; import org.apache.http.StatusLine; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.utils.DateUtils; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpRequest; import org.apache.http.message.BasicHttpResponse; import org.apache.http.message.BasicStatusLine; import org.junit.Assert; public class HttpTestUtils { /* * "The following HTTP/1.1 headers are hop-by-hop headers..." * * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1 */ private static final String[] HOP_BY_HOP_HEADERS = { "Connection", "Keep-Alive", "Proxy-Authenticate", "Proxy-Authorization", "TE", "Trailers", "Transfer-Encoding", "Upgrade" }; /* * "Multiple message-header fields with the same field-name MAY be present * in a message if and only if the entire field-value for that header field * is defined as a comma-separated list [i.e., #(values)]." * * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 */ private static final String[] MULTI_HEADERS = { "Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language", "Allow", "Cache-Control", "Connection", "Content-Encoding", "Content-Language", "Expect", "Pragma", "Proxy-Authenticate", "TE", "Trailer", "Transfer-Encoding", "Upgrade", "Via", "Warning", "WWW-Authenticate" }; private static final String[] SINGLE_HEADERS = { "Accept-Ranges", "Age", "Authorization", "Content-Length", "Content-Location", "Content-MD5", "Content-Range", "Content-Type", "Date", "ETag", "Expires", "From", "Host", "If-Match", "If-Modified-Since", "If-None-Match", "If-Range", "If-Unmodified-Since", "Last-Modified", "Location", "Max-Forwards", "Proxy-Authorization", "Range", "Referer", "Retry-After", "Server", "User-Agent", "Vary" }; /* * "Entity-header fields define metainformation about the entity-body or, * if no body is present, about the resource identified by the request." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.1 */ public static final String[] ENTITY_HEADERS = { "Allow", "Content-Encoding", "Content-Language", "Content-Length", "Content-Location", "Content-MD5", "Content-Range", "Content-Type", "Expires", "Last-Modified" }; /* * Determines whether the given header name is considered a hop-by-hop * header. * * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1 */ public static boolean isHopByHopHeader(final String name) { for (final String s : HOP_BY_HOP_HEADERS) { if (s.equalsIgnoreCase(name)) { return true; } } return false; } /* * Determines whether a given header name may appear multiple times. */ public static boolean isMultiHeader(final String name) { for (final String s : MULTI_HEADERS) { if (s.equalsIgnoreCase(name)) { return true; } } return false; } /* * Determines whether a given header name may only appear once in a message. */ public static boolean isSingleHeader(final String name) { for (final String s : SINGLE_HEADERS) { if (s.equalsIgnoreCase(name)) { return true; } } return false; } /* * Assert.asserts that two request or response bodies are byte-equivalent. */ public static boolean equivalent(final HttpEntity e1, final HttpEntity e2) throws Exception { final InputStream i1 = e1.getContent(); final InputStream i2 = e2.getContent(); if (i1 == null && i2 == null) { return true; } if (i1 == null || i2 == null) { return false; // avoid possible NPEs below } int b1 = -1; while ((b1 = i1.read()) != -1) { if (b1 != i2.read()) { return false; } } return (-1 == i2.read()); } /* * Assert.asserts that the components of two status lines match in a way * that differs only by hop-by-hop information. "2.1 Proxy Behavior ...We * remind the reader that HTTP version numbers are hop-by-hop components of * HTTP meesages, and are not end-to-end." * * @see http://www.ietf.org/rfc/rfc2145.txt */ public static boolean semanticallyTransparent(final StatusLine l1, final StatusLine l2) { return (l1.getReasonPhrase().equals(l2.getReasonPhrase()) && l1.getStatusCode() == l2 .getStatusCode()); } /* Assert.asserts that the components of two status lines match. */ public static boolean equivalent(final StatusLine l1, final StatusLine l2) { return (l1.getProtocolVersion().equals(l2.getProtocolVersion()) && semanticallyTransparent( l1, l2)); } /* Assert.asserts that the components of two request lines match. */ public static boolean equivalent(final RequestLine l1, final RequestLine l2) { return (l1.getMethod().equals(l2.getMethod()) && l1.getProtocolVersion().equals(l2.getProtocolVersion()) && l1.getUri().equals( l2.getUri())); } /* * Retrieves the full header value by combining multiple headers and * separating with commas, canonicalizing whitespace along the way. * * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 */ public static String getCanonicalHeaderValue(final HttpMessage r, final String name) { if (isSingleHeader(name)) { final Header h = r.getFirstHeader(name); return (h != null) ? h.getValue() : null; } final StringBuilder buf = new StringBuilder(); boolean first = true; for (final Header h : r.getHeaders(name)) { if (!first) { buf.append(", "); } buf.append(h.getValue().trim()); first = false; } return buf.toString(); } /* * Assert.asserts that all the headers appearing in r1 also appear in r2 * with the same canonical header values. */ public static boolean isEndToEndHeaderSubset(final HttpMessage r1, final HttpMessage r2) { for (final Header h : r1.getAllHeaders()) { if (!isHopByHopHeader(h.getName())) { final String r1val = getCanonicalHeaderValue(r1, h.getName()); final String r2val = getCanonicalHeaderValue(r2, h.getName()); if (!r1val.equals(r2val)) { return false; } } } return true; } /* * Assert.asserts that message r2 represents exactly the same * message as r1, except for hop-by-hop headers. "When a cache * is semantically transparent, the client receives exactly the same * response (except for hop-by-hop headers) that it would have received had * its request been handled directly by the origin server." * * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec1.html#sec1.3 */ public static boolean semanticallyTransparent(final HttpResponse r1, final HttpResponse r2) throws Exception { final boolean entitiesEquivalent = equivalent(r1.getEntity(), r2.getEntity()); if (!entitiesEquivalent) { return false; } final boolean statusLinesEquivalent = semanticallyTransparent(r1.getStatusLine(), r2.getStatusLine()); if (!statusLinesEquivalent) { return false; } final boolean e2eHeadersEquivalentSubset = isEndToEndHeaderSubset( r1, r2); return e2eHeadersEquivalentSubset; } /* Assert.asserts that two requests are morally equivalent. */ public static boolean equivalent(final HttpRequest r1, final HttpRequest r2) { return (equivalent(r1.getRequestLine(), r2.getRequestLine()) && isEndToEndHeaderSubset(r1, r2)); } /* Assert.asserts that two requests are morally equivalent. */ public static boolean equivalent(final HttpResponse r1, final HttpResponse r2) { return (equivalent(r1.getStatusLine(), r2.getStatusLine()) && isEndToEndHeaderSubset(r1, r2)); } public static byte[] getRandomBytes(final int nbytes) { final byte[] bytes = new byte[nbytes]; new Random().nextBytes(bytes); return bytes; } /** Generates a response body with random content. * @param nbytes length of the desired response body * @return an {@link HttpEntity} */ public static HttpEntity makeBody(final int nbytes) { return new ByteArrayEntity(getRandomBytes(nbytes)); } public static HttpCacheEntry makeCacheEntry(final Date requestDate, final Date responseDate) { final Date when = new Date((responseDate.getTime() + requestDate.getTime()) / 2); return makeCacheEntry(requestDate, responseDate, getStockHeaders(when)); } public static Header[] getStockHeaders(final Date when) { final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(when)), new BasicHeader("Server", "MockServer/1.0") }; return headers; } public static HttpCacheEntry makeCacheEntry(final Date requestDate, final Date responseDate, final Header[] headers) { final byte[] bytes = getRandomBytes(128); return makeCacheEntry(requestDate, responseDate, headers, bytes); } public static HttpCacheEntry makeCacheEntry(final Date requestDate, final Date responseDate, final Header[] headers, final byte[] bytes) { final Map variantMap = null; return makeCacheEntry(requestDate, responseDate, headers, bytes, variantMap); } public static HttpCacheEntry makeCacheEntry(final Map variantMap) { final Date now = new Date(); return makeCacheEntry(now, now, getStockHeaders(now), getRandomBytes(128), variantMap); } public static HttpCacheEntry makeCacheEntry(final Date requestDate, final Date responseDate, final Header[] headers, final byte[] bytes, final Map variantMap) { final StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); return new HttpCacheEntry(requestDate, responseDate, statusLine, headers, new HeapResource(bytes), variantMap); } public static HttpCacheEntry makeCacheEntry(final Header[] headers, final byte[] bytes) { final Date now = new Date(); return makeCacheEntry(now, now, headers, bytes); } public static HttpCacheEntry makeCacheEntry(final byte[] bytes) { return makeCacheEntry(getStockHeaders(new Date()), bytes); } public static HttpCacheEntry makeCacheEntry(final Header[] headers) { return makeCacheEntry(headers, getRandomBytes(128)); } public static HttpCacheEntry makeCacheEntry() { final Date now = new Date(); return makeCacheEntry(now, now); } public static HttpResponse make200Response() { final HttpResponse out = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); out.setHeader("Date", DateUtils.formatDate(new Date())); out.setHeader("Server", "MockOrigin/1.0"); out.setHeader("Content-Length", "128"); out.setEntity(makeBody(128)); return out; } public static final HttpResponse make200Response(final Date date, final String cacheControl) { final HttpResponse response = HttpTestUtils.make200Response(); response.setHeader("Date", DateUtils.formatDate(date)); response.setHeader("Cache-Control",cacheControl); response.setHeader("Etag","\"etag\""); return response; } public static final void assert110WarningFound(final HttpResponse response) { boolean found110Warning = false; for(final Header h : response.getHeaders("Warning")) { for(final HeaderElement elt : h.getElements()) { final String[] parts = elt.getName().split("\\s"); if ("110".equals(parts[0])) { found110Warning = true; break; } } } Assert.assertTrue(found110Warning); } public static HttpRequest makeDefaultRequest() { return new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); } public static HttpResponse make500Response() { return new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_INTERNAL_SERVER_ERROR, "Internal Server Error"); } } ././@LongLink0100644 0000000 0000000 00000000153 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/OKStatus.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/OKStatu0100644 0000000 0000000 00000003034 12301751715 032247 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.message.BasicStatusLine; public class OKStatus extends BasicStatusLine { private static final long serialVersionUID = -1639872615816850272L; public OKStatus() { super(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); } } ././@LongLink0100644 0000000 0000000 00000000164 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/RequestEquivalent.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/Request0100644 0000000 0000000 00000003566 12301751716 032360 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.apache.http.HttpRequest; import org.easymock.IArgumentMatcher; public class RequestEquivalent implements IArgumentMatcher { private final HttpRequest expected; public RequestEquivalent(final HttpRequest expected) { this.expected = expected; } public boolean matches(final Object actual) { if (!(actual instanceof HttpRequest)) { return false; } final HttpRequest other = (HttpRequest) actual; return HttpTestUtils.equivalent(expected, other); } public void appendTo(final StringBuffer buf) { buf.append("eqRequest("); buf.append(expected); buf.append(")"); } } ././@LongLink0100644 0000000 0000000 00000000165 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ResponseEquivalent.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/Respons0100644 0000000 0000000 00000003576 12301751715 032361 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.apache.http.HttpResponse; import org.easymock.IArgumentMatcher; public class ResponseEquivalent implements IArgumentMatcher { private final HttpResponse expected; public ResponseEquivalent(final HttpResponse expected) { this.expected = expected; } public boolean matches(final Object actual) { if (!(actual instanceof HttpResponse)) { return false; } final HttpResponse other = (HttpResponse) actual; return HttpTestUtils.equivalent(expected, other); } public void appendTo(final StringBuffer buf) { buf.append("eqRequest("); buf.append(expected); buf.append(")"); } } ././@LongLink0100644 0000000 0000000 00000000155 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/Serializer.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/Seriali0100644 0000000 0000000 00000004036 12301751715 032310 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class Serializer { public byte[] serialize(final T object) throws Exception { final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); final ObjectOutputStream objectStream = new ObjectOutputStream(byteStream); objectStream.writeObject(object); return byteStream.toByteArray(); } @SuppressWarnings("unchecked") public T deserialize(final byte[] serialized) throws Exception { final ByteArrayInputStream byteStream = new ByteArrayInputStream(serialized); final ObjectInputStream objectStream = new ObjectInputStream(byteStream); final T object = (T) objectStream.readObject(); return object; } } ././@LongLink0100644 0000000 0000000 00000000171 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/SimpleHttpCacheStorage.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/SimpleH0100644 0000000 0000000 00000004341 12301751715 032260 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.client.cache.HttpCacheUpdateCallback; class SimpleHttpCacheStorage implements HttpCacheStorage { public final Map map; public SimpleHttpCacheStorage() { map = new HashMap(); } public void putEntry(final String key, final HttpCacheEntry entry) throws IOException { map.put(key, entry); } public HttpCacheEntry getEntry(final String key) throws IOException { return map.get(key); } public void removeEntry(final String key) throws IOException { map.remove(key); } public void updateEntry(final String key, final HttpCacheUpdateCallback callback) throws IOException { final HttpCacheEntry v1 = map.get(key); final HttpCacheEntry v2 = callback.update(v1); map.put(key,v2); } } ././@LongLink0100644 0000000 0000000 00000000204 12302131606 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestAsynchronousValidationRequest.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestAsy0100644 0000000 0000000 00000020455 12301751715 032317 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.ProtocolException; import org.apache.http.StatusLine; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.message.BasicHeader; import org.easymock.classextension.EasyMock; import org.junit.Before; import org.junit.Test; public class TestAsynchronousValidationRequest { private AsynchronousValidator mockParent; private CachingExec mockClient; private HttpRoute route; private HttpRequestWrapper request; private HttpClientContext context; private HttpExecutionAware mockExecAware; private HttpCacheEntry mockCacheEntry; private CloseableHttpResponse mockResponse; private StatusLine mockStatusLine; @Before public void setUp() { mockParent = EasyMock.createNiceMock(AsynchronousValidator.class); mockClient = EasyMock.createNiceMock(CachingExec.class); route = new HttpRoute(new HttpHost("foo.example.com")); request = HttpRequestWrapper.wrap(new HttpGet("/")); context = HttpClientContext.create(); mockExecAware = EasyMock.createNiceMock(HttpExecutionAware.class); mockCacheEntry = EasyMock.createNiceMock(HttpCacheEntry.class); mockResponse = EasyMock.createNiceMock(CloseableHttpResponse.class); mockStatusLine = EasyMock.createNiceMock(StatusLine.class); } @Test public void testRunCallsCachingClientAndRemovesIdentifier() throws Exception { final String identifier = "foo"; final AsynchronousValidationRequest impl = new AsynchronousValidationRequest( mockParent, mockClient, route, request, context, mockExecAware, mockCacheEntry, identifier, 0); EasyMock.expect( mockClient.revalidateCacheEntry( route, request, context, mockExecAware, mockCacheEntry)).andReturn(mockResponse); EasyMock.expect(mockResponse.getStatusLine()).andReturn(mockStatusLine); EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(200); mockParent.markComplete(identifier); mockParent.jobSuccessful(identifier); replayMocks(); impl.run(); verifyMocks(); } @Test public void testRunReportsJobFailedForServerError() throws Exception { final String identifier = "foo"; final AsynchronousValidationRequest impl = new AsynchronousValidationRequest( mockParent, mockClient, route, request, context, mockExecAware, mockCacheEntry, identifier, 0); EasyMock.expect( mockClient.revalidateCacheEntry( route, request, context, mockExecAware, mockCacheEntry)).andReturn(mockResponse); EasyMock.expect(mockResponse.getStatusLine()).andReturn(mockStatusLine); EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(200); mockParent.markComplete(identifier); mockParent.jobSuccessful(identifier); replayMocks(); impl.run(); verifyMocks(); } @Test public void testRunReportsJobFailedForStaleResponse() throws Exception { final String identifier = "foo"; final Header[] warning = new Header[] {new BasicHeader(HeaderConstants.WARNING, "110 localhost \"Response is stale\"")}; final AsynchronousValidationRequest impl = new AsynchronousValidationRequest( mockParent, mockClient, route, request, context, mockExecAware, mockCacheEntry, identifier, 0); EasyMock.expect( mockClient.revalidateCacheEntry( route, request, context, mockExecAware, mockCacheEntry)).andReturn(mockResponse); EasyMock.expect(mockResponse.getStatusLine()).andReturn(mockStatusLine); EasyMock.expect(mockStatusLine.getStatusCode()).andReturn(200); EasyMock.expect(mockResponse.getHeaders(HeaderConstants.WARNING)).andReturn(warning); mockParent.markComplete(identifier); mockParent.jobFailed(identifier); replayMocks(); impl.run(); verifyMocks(); } @Test public void testRunGracefullyHandlesProtocolException() throws Exception { final String identifier = "foo"; final AsynchronousValidationRequest impl = new AsynchronousValidationRequest( mockParent, mockClient, route, request, context, mockExecAware, mockCacheEntry, identifier, 0); EasyMock.expect( mockClient.revalidateCacheEntry( route, request, context, mockExecAware, mockCacheEntry)).andThrow( new ProtocolException()); mockParent.markComplete(identifier); mockParent.jobFailed(identifier); replayMocks(); impl.run(); verifyMocks(); } @Test public void testRunGracefullyHandlesIOException() throws Exception { final String identifier = "foo"; final AsynchronousValidationRequest impl = new AsynchronousValidationRequest( mockParent, mockClient, route, request, context, mockExecAware, mockCacheEntry, identifier, 0); EasyMock.expect( mockClient.revalidateCacheEntry( route, request, context, mockExecAware, mockCacheEntry)).andThrow( new IOException()); mockParent.markComplete(identifier); mockParent.jobFailed(identifier); replayMocks(); impl.run(); verifyMocks(); } @Test public void testRunGracefullyHandlesRuntimeException() throws Exception { final String identifier = "foo"; final AsynchronousValidationRequest impl = new AsynchronousValidationRequest( mockParent, mockClient, route, request, context, mockExecAware, mockCacheEntry, identifier, 0); EasyMock.expect( mockClient.revalidateCacheEntry( route, request, context, mockExecAware, mockCacheEntry)).andThrow( new RuntimeException()); mockParent.markComplete(identifier); mockParent.jobFailed(identifier); replayMocks(); impl.run(); verifyMocks(); } public void replayMocks() { EasyMock.replay(mockClient); EasyMock.replay(mockExecAware); EasyMock.replay(mockCacheEntry); EasyMock.replay(mockResponse); EasyMock.replay(mockStatusLine); EasyMock.replay(mockParent); } public void verifyMocks() { EasyMock.verify(mockClient); EasyMock.verify(mockExecAware); EasyMock.verify(mockCacheEntry); EasyMock.verify(mockResponse); EasyMock.verify(mockStatusLine); EasyMock.verify(mockParent); } } ././@LongLink0100644 0000000 0000000 00000000174 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestAsynchronousValidator.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestAsy0100644 0000000 0000000 00000020761 12301751715 032317 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.message.BasicHeader; import org.easymock.Capture; import org.easymock.classextension.EasyMock; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestAsynchronousValidator { private AsynchronousValidator impl; private CachingExec mockClient; private HttpRoute route; private HttpRequestWrapper request; private HttpClientContext context; private HttpExecutionAware mockExecAware; private HttpCacheEntry mockCacheEntry; private SchedulingStrategy mockSchedulingStrategy; @Before public void setUp() { mockClient = EasyMock.createNiceMock(CachingExec.class); route = new HttpRoute(new HttpHost("foo.example.com")); request = HttpRequestWrapper.wrap(new HttpGet("/")); context = HttpClientContext.create(); context.setTargetHost(new HttpHost("foo.example.com")); mockExecAware = EasyMock.createNiceMock(HttpExecutionAware.class); mockCacheEntry = EasyMock.createNiceMock(HttpCacheEntry.class); mockSchedulingStrategy = EasyMock.createNiceMock(SchedulingStrategy.class); } @Test public void testRevalidateCacheEntrySchedulesExecutionAndPopulatesIdentifier() { impl = new AsynchronousValidator(mockSchedulingStrategy); EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false); mockSchedulingStrategy.schedule(EasyMock.isA(AsynchronousValidationRequest.class)); replayMocks(); impl.revalidateCacheEntry(mockClient, route, request, context, mockExecAware, mockCacheEntry); verifyMocks(); Assert.assertEquals(1, impl.getScheduledIdentifiers().size()); } @Test public void testMarkCompleteRemovesIdentifier() { impl = new AsynchronousValidator(mockSchedulingStrategy); EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false); final Capture cap = new Capture(); mockSchedulingStrategy.schedule(EasyMock.capture(cap)); replayMocks(); impl.revalidateCacheEntry(mockClient, route, request, context, mockExecAware, mockCacheEntry); verifyMocks(); Assert.assertEquals(1, impl.getScheduledIdentifiers().size()); impl.markComplete(cap.getValue().getIdentifier()); Assert.assertEquals(0, impl.getScheduledIdentifiers().size()); } @Test public void testRevalidateCacheEntryDoesNotPopulateIdentifierOnRejectedExecutionException() { impl = new AsynchronousValidator(mockSchedulingStrategy); EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false); mockSchedulingStrategy.schedule(EasyMock.isA(AsynchronousValidationRequest.class)); EasyMock.expectLastCall().andThrow(new RejectedExecutionException()); replayMocks(); impl.revalidateCacheEntry(mockClient, route, request, context, mockExecAware, mockCacheEntry); verifyMocks(); Assert.assertEquals(0, impl.getScheduledIdentifiers().size()); } @Test public void testRevalidateCacheEntryProperlyCollapsesRequest() { impl = new AsynchronousValidator(mockSchedulingStrategy); EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false); mockSchedulingStrategy.schedule(EasyMock.isA(AsynchronousValidationRequest.class)); EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false); replayMocks(); impl.revalidateCacheEntry(mockClient, route, request, context, mockExecAware, mockCacheEntry); impl.revalidateCacheEntry(mockClient, route, request, context, mockExecAware, mockCacheEntry); verifyMocks(); Assert.assertEquals(1, impl.getScheduledIdentifiers().size()); } @Test public void testVariantsBothRevalidated() { impl = new AsynchronousValidator(mockSchedulingStrategy); final HttpRequest req1 = new HttpGet("/"); req1.addHeader(new BasicHeader("Accept-Encoding", "identity")); final HttpRequest req2 = new HttpGet("/"); req2.addHeader(new BasicHeader("Accept-Encoding", "gzip")); final Header[] variantHeaders = new Header[] { new BasicHeader(HeaderConstants.VARY, "Accept-Encoding") }; EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(true).times(2); EasyMock.expect(mockCacheEntry.getHeaders(HeaderConstants.VARY)).andReturn(variantHeaders).times(2); mockSchedulingStrategy.schedule(EasyMock.isA(AsynchronousValidationRequest.class)); EasyMock.expectLastCall().times(2); replayMocks(); impl.revalidateCacheEntry(mockClient, route, HttpRequestWrapper.wrap(req1), context, mockExecAware, mockCacheEntry); impl.revalidateCacheEntry(mockClient, route, HttpRequestWrapper.wrap(req2), context, mockExecAware, mockCacheEntry); verifyMocks(); Assert.assertEquals(2, impl.getScheduledIdentifiers().size()); } @Test public void testRevalidateCacheEntryEndToEnd() throws Exception { final CacheConfig config = CacheConfig.custom() .setAsynchronousWorkersMax(1) .setAsynchronousWorkersCore(1) .build(); final ImmediateSchedulingStrategy schedulingStrategy = new ImmediateSchedulingStrategy(config); impl = new AsynchronousValidator(schedulingStrategy); EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false); EasyMock.expect(mockClient.revalidateCacheEntry( route, request, context, mockExecAware, mockCacheEntry)).andReturn(null); replayMocks(); impl.revalidateCacheEntry(mockClient, route, request, context, mockExecAware, mockCacheEntry); try { // shut down backend executor and make sure all finishes properly, 1 second should be sufficient schedulingStrategy.close(); schedulingStrategy.awaitTermination(1, TimeUnit.SECONDS); } catch (final InterruptedException ie) { } finally { verifyMocks(); Assert.assertEquals(0, impl.getScheduledIdentifiers().size()); } } @Test public void testSchedulingStrategyShutdownOnClose() throws IOException { impl = new AsynchronousValidator(mockSchedulingStrategy); mockSchedulingStrategy.close(); replayMocks(); impl.close(); verifyMocks(); } public void replayMocks() { EasyMock.replay(mockSchedulingStrategy); EasyMock.replay(mockClient); EasyMock.replay(mockExecAware); EasyMock.replay(mockCacheEntry); } public void verifyMocks() { EasyMock.verify(mockSchedulingStrategy); EasyMock.verify(mockClient); EasyMock.verify(mockExecAware); EasyMock.verify(mockCacheEntry); } } ././@LongLink0100644 0000000 0000000 00000000165 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestBasicHttpCache.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestBas0100644 0000000 0000000 00000057722 12301751715 032277 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.Resource; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpOptions; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpTrace; import org.apache.http.client.utils.DateUtils; import org.apache.http.entity.BasicHttpEntity; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpResponse; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestBasicHttpCache { private BasicHttpCache impl; private SimpleHttpCacheStorage backing; @Before public void setUp() throws Exception { backing = new SimpleHttpCacheStorage(); impl = new BasicHttpCache(new HeapResourceFactory(), backing, CacheConfig.DEFAULT); } @Test public void testDoNotFlushCacheEntriesOnGet() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req = new HttpGet("/bar"); final String key = (new CacheKeyGenerator()).getURI(host, req); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); backing.map.put(key, entry); impl.flushCacheEntriesFor(host, req); assertEquals(entry, backing.map.get(key)); } @Test public void testDoNotFlushCacheEntriesOnHead() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req = new HttpHead("/bar"); final String key = (new CacheKeyGenerator()).getURI(host, req); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); backing.map.put(key, entry); impl.flushCacheEntriesFor(host, req); assertEquals(entry, backing.map.get(key)); } @Test public void testDoNotFlushCacheEntriesOnOptions() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req = new HttpOptions("/bar"); final String key = (new CacheKeyGenerator()).getURI(host, req); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); backing.map.put(key, entry); impl.flushCacheEntriesFor(host, req); assertEquals(entry, backing.map.get(key)); } @Test public void testDoNotFlushCacheEntriesOnTrace() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req = new HttpTrace("/bar"); final String key = (new CacheKeyGenerator()).getURI(host, req); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); backing.map.put(key, entry); impl.flushCacheEntriesFor(host, req); assertEquals(entry, backing.map.get(key)); } @Test public void testFlushContentLocationEntryIfUnSafeRequest() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req = new HttpPost("/foo"); final HttpResponse resp = HttpTestUtils.make200Response(); resp.setHeader("Content-Location", "/bar"); resp.setHeader(HeaderConstants.ETAG, "\"etag\""); final String key = (new CacheKeyGenerator()).getURI(host, new HttpGet("/bar")); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("Date", DateUtils.formatDate(new Date())), new BasicHeader("ETag", "\"old-etag\"") }); backing.map.put(key, entry); impl.flushInvalidatedCacheEntriesFor(host, req, resp); assertNull(backing.map.get(key)); } @Test public void testDoNotFlushContentLocationEntryIfSafeRequest() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req = new HttpGet("/foo"); final HttpResponse resp = HttpTestUtils.make200Response(); resp.setHeader("Content-Location", "/bar"); final String key = (new CacheKeyGenerator()).getURI(host, new HttpGet("/bar")); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("Date", DateUtils.formatDate(new Date())), new BasicHeader("ETag", "\"old-etag\"") }); backing.map.put(key, entry); impl.flushInvalidatedCacheEntriesFor(host, req, resp); assertEquals(entry, backing.map.get(key)); } @Test public void testCanFlushCacheEntriesAtUri() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req = new HttpDelete("/bar"); final String key = (new CacheKeyGenerator()).getURI(host, req); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); backing.map.put(key, entry); impl.flushCacheEntriesFor(host, req); assertNull(backing.map.get(key)); } @Test public void testRecognizesComplete200Response() throws Exception { final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); final byte[] bytes = HttpTestUtils.getRandomBytes(128); resp.setEntity(new ByteArrayEntity(bytes)); resp.setHeader("Content-Length","128"); final Resource resource = new HeapResource(bytes); assertFalse(impl.isIncompleteResponse(resp, resource)); } @Test public void testRecognizesComplete206Response() throws Exception { final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); final byte[] bytes = HttpTestUtils.getRandomBytes(128); final Resource resource = new HeapResource(bytes); resp.setEntity(new ByteArrayEntity(bytes)); resp.setHeader("Content-Length","128"); resp.setHeader("Content-Range","bytes 0-127/255"); assertFalse(impl.isIncompleteResponse(resp, resource)); } @Test public void testRecognizesIncomplete200Response() throws Exception { final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); final byte[] bytes = HttpTestUtils.getRandomBytes(128); final Resource resource = new HeapResource(bytes); resp.setEntity(new ByteArrayEntity(bytes)); resp.setHeader("Content-Length","256"); assertTrue(impl.isIncompleteResponse(resp, resource)); } @Test public void testIgnoresIncompleteNon200Or206Responses() throws Exception { final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_FORBIDDEN, "Forbidden"); final byte[] bytes = HttpTestUtils.getRandomBytes(128); final Resource resource = new HeapResource(bytes); resp.setEntity(new ByteArrayEntity(bytes)); resp.setHeader("Content-Length","256"); assertFalse(impl.isIncompleteResponse(resp, resource)); } @Test public void testResponsesWithoutExplicitContentLengthAreComplete() throws Exception { final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); final byte[] bytes = HttpTestUtils.getRandomBytes(128); final Resource resource = new HeapResource(bytes); resp.setEntity(new ByteArrayEntity(bytes)); assertFalse(impl.isIncompleteResponse(resp, resource)); } @Test public void testResponsesWithUnparseableContentLengthHeaderAreComplete() throws Exception { final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); final byte[] bytes = HttpTestUtils.getRandomBytes(128); final Resource resource = new HeapResource(bytes); resp.setHeader("Content-Length","foo"); resp.setEntity(new ByteArrayEntity(bytes)); assertFalse(impl.isIncompleteResponse(resp, resource)); } @Test public void testIncompleteResponseErrorProvidesPlainTextErrorMessage() throws Exception { final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); final byte[] bytes = HttpTestUtils.getRandomBytes(128); final Resource resource = new HeapResource(bytes); resp.setEntity(new ByteArrayEntity(bytes)); resp.setHeader("Content-Length","256"); final HttpResponse result = impl.generateIncompleteResponseError(resp, resource); final Header ctype = result.getFirstHeader("Content-Type"); assertEquals("text/plain;charset=UTF-8", ctype.getValue()); } @Test public void testIncompleteResponseErrorProvidesNonEmptyErrorMessage() throws Exception { final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); final byte[] bytes = HttpTestUtils.getRandomBytes(128); final Resource resource = new HeapResource(bytes); resp.setEntity(new ByteArrayEntity(bytes)); resp.setHeader("Content-Length","256"); final HttpResponse result = impl.generateIncompleteResponseError(resp, resource); final int clen = Integer.parseInt(result.getFirstHeader("Content-Length").getValue()); assertTrue(clen > 0); final HttpEntity body = result.getEntity(); if (body.getContentLength() < 0) { final InputStream is = body.getContent(); int bytes_read = 0; while((is.read()) != -1) { bytes_read++; } is.close(); assertEquals(clen, bytes_read); } else { assertTrue(body.getContentLength() == clen); } } @Test public void testCacheUpdateAddsVariantURIToParentEntry() throws Exception { final String parentCacheKey = "parentCacheKey"; final String variantCacheKey = "variantCacheKey"; final String existingVariantKey = "existingVariantKey"; final String newVariantCacheKey = "newVariantCacheKey"; final String newVariantKey = "newVariantKey"; final Map existingVariants = new HashMap(); existingVariants.put(existingVariantKey, variantCacheKey); final HttpCacheEntry parent = HttpTestUtils.makeCacheEntry(existingVariants); final HttpCacheEntry variant = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry result = impl.doGetUpdatedParentEntry(parentCacheKey, parent, variant, newVariantKey, newVariantCacheKey); final Map resultMap = result.getVariantMap(); assertEquals(2, resultMap.size()); assertEquals(variantCacheKey, resultMap.get(existingVariantKey)); assertEquals(newVariantCacheKey, resultMap.get(newVariantKey)); } @Test public void testStoreInCachePutsNonVariantEntryInPlace() throws Exception { final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); assertFalse(entry.hasVariants()); final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req = new HttpGet("http://foo.example.com/bar"); final String key = (new CacheKeyGenerator()).getURI(host, req); impl.storeInCache(host, req, entry); assertSame(entry, backing.map.get(key)); } @Test public void testTooLargeResponsesAreNotCached() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest request = new HttpGet("http://foo.example.com/bar"); final Date now = new Date(); final Date requestSent = new Date(now.getTime() - 3 * 1000L); final Date responseGenerated = new Date(now.getTime() - 2 * 1000L); final Date responseReceived = new Date(now.getTime() - 1 * 1000L); final HttpResponse originResponse = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); originResponse.setEntity(HttpTestUtils.makeBody(CacheConfig.DEFAULT_MAX_OBJECT_SIZE_BYTES + 1)); originResponse.setHeader("Cache-Control","public, max-age=3600"); originResponse.setHeader("Date", DateUtils.formatDate(responseGenerated)); originResponse.setHeader("ETag", "\"etag\""); final HttpResponse result = impl.cacheAndReturnResponse(host, request, originResponse, requestSent, responseReceived); assertEquals(0, backing.map.size()); assertTrue(HttpTestUtils.semanticallyTransparent(originResponse, result)); } @Test public void testSmallEnoughResponsesAreCached() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest request = new HttpGet("http://foo.example.com/bar"); final Date now = new Date(); final Date requestSent = new Date(now.getTime() - 3 * 1000L); final Date responseGenerated = new Date(now.getTime() - 2 * 1000L); final Date responseReceived = new Date(now.getTime() - 1 * 1000L); final HttpResponse originResponse = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); originResponse.setEntity(HttpTestUtils.makeBody(CacheConfig.DEFAULT_MAX_OBJECT_SIZE_BYTES - 1)); originResponse.setHeader("Cache-Control","public, max-age=3600"); originResponse.setHeader("Date", DateUtils.formatDate(responseGenerated)); originResponse.setHeader("ETag", "\"etag\""); final HttpResponse result = impl.cacheAndReturnResponse(host, request, originResponse, requestSent, responseReceived); assertEquals(1, backing.map.size()); assertTrue(backing.map.containsKey((new CacheKeyGenerator()).getURI(host, request))); assertTrue(HttpTestUtils.semanticallyTransparent(originResponse, result)); } @Test public void testGetCacheEntryReturnsNullOnCacheMiss() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest request = new HttpGet("http://foo.example.com/bar"); final HttpCacheEntry result = impl.getCacheEntry(host, request); Assert.assertNull(result); } @Test public void testGetCacheEntryFetchesFromCacheOnCacheHitIfNoVariants() throws Exception { final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); assertFalse(entry.hasVariants()); final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest request = new HttpGet("http://foo.example.com/bar"); final String key = (new CacheKeyGenerator()).getURI(host, request); backing.map.put(key,entry); final HttpCacheEntry result = impl.getCacheEntry(host, request); Assert.assertSame(entry, result); } @Test public void testGetCacheEntryReturnsNullIfNoVariantInCache() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest request = new HttpGet("http://foo.example.com/bar"); final HttpRequest origRequest = new HttpGet("http://foo.example.com/bar"); origRequest.setHeader("Accept-Encoding","gzip"); final HttpResponse origResponse = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); origResponse.setEntity(HttpTestUtils.makeBody(128)); origResponse.setHeader("Date", DateUtils.formatDate(new Date())); origResponse.setHeader("Cache-Control", "max-age=3600, public"); origResponse.setHeader("ETag", "\"etag\""); origResponse.setHeader("Vary", "Accept-Encoding"); origResponse.setHeader("Content-Encoding","gzip"); impl.cacheAndReturnResponse(host, origRequest, origResponse, new Date(), new Date()); final HttpCacheEntry result = impl.getCacheEntry(host, request); assertNull(result); } @Test public void testGetCacheEntryReturnsVariantIfPresentInCache() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest request = new HttpGet("http://foo.example.com/bar"); request.setHeader("Accept-Encoding","gzip"); final HttpRequest origRequest = new HttpGet("http://foo.example.com/bar"); origRequest.setHeader("Accept-Encoding","gzip"); final HttpResponse origResponse = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); origResponse.setEntity(HttpTestUtils.makeBody(128)); origResponse.setHeader("Date", DateUtils.formatDate(new Date())); origResponse.setHeader("Cache-Control", "max-age=3600, public"); origResponse.setHeader("ETag", "\"etag\""); origResponse.setHeader("Vary", "Accept-Encoding"); origResponse.setHeader("Content-Encoding","gzip"); impl.cacheAndReturnResponse(host, origRequest, origResponse, new Date(), new Date()); final HttpCacheEntry result = impl.getCacheEntry(host, request); assertNotNull(result); } @Test public void testGetVariantCacheEntriesReturnsEmptySetOnNoVariants() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest request = new HttpGet("http://foo.example.com/bar"); final Map variants = impl.getVariantCacheEntriesWithEtags(host, request); assertNotNull(variants); assertEquals(0, variants.size()); } @Test public void testGetVariantCacheEntriesReturnsAllVariants() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req1 = new HttpGet("http://foo.example.com/bar"); req1.setHeader("Accept-Encoding", "gzip"); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(new Date())); resp1.setHeader("Cache-Control", "max-age=3600, public"); resp1.setHeader("ETag", "\"etag1\""); resp1.setHeader("Vary", "Accept-Encoding"); resp1.setHeader("Content-Encoding","gzip"); resp1.setHeader("Vary", "Accept-Encoding"); final HttpRequest req2 = new HttpGet("http://foo.example.com/bar"); req2.setHeader("Accept-Encoding", "identity"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Date", DateUtils.formatDate(new Date())); resp2.setHeader("Cache-Control", "max-age=3600, public"); resp2.setHeader("ETag", "\"etag2\""); resp2.setHeader("Vary", "Accept-Encoding"); resp2.setHeader("Content-Encoding","gzip"); resp2.setHeader("Vary", "Accept-Encoding"); impl.cacheAndReturnResponse(host, req1, resp1, new Date(), new Date()); impl.cacheAndReturnResponse(host, req2, resp2, new Date(), new Date()); final Map variants = impl.getVariantCacheEntriesWithEtags(host, req1); assertNotNull(variants); assertEquals(2, variants.size()); } @Test public void testOriginalResponseWithNoContentSizeHeaderIsReleased() throws Exception { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest request = new HttpGet("http://foo.example.com/bar"); final Date now = new Date(); final Date requestSent = new Date(now.getTime() - 3 * 1000L); final Date responseGenerated = new Date(now.getTime() - 2 * 1000L); final Date responseReceived = new Date(now.getTime() - 1 * 1000L); final HttpResponse originResponse = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); final BasicHttpEntity entity = new BasicHttpEntity(); final ConsumableInputStream inputStream = new ConsumableInputStream(new ByteArrayInputStream(HttpTestUtils.getRandomBytes(CacheConfig.DEFAULT_MAX_OBJECT_SIZE_BYTES - 1))); entity.setContent(inputStream); originResponse.setEntity(entity); originResponse.setHeader("Cache-Control","public, max-age=3600"); originResponse.setHeader("Date", DateUtils.formatDate(responseGenerated)); originResponse.setHeader("ETag", "\"etag\""); final HttpResponse result = impl.cacheAndReturnResponse(host, request, originResponse, requestSent, responseReceived); IOUtils.consume(result.getEntity()); assertTrue(inputStream.wasClosed()); } static class DisposableResource implements Resource { private static final long serialVersionUID = 1L; private final byte[] b; private boolean dispoased; public DisposableResource(final byte[] b) { super(); this.b = b; } byte[] getByteArray() { return this.b; } public InputStream getInputStream() throws IOException { if (dispoased) { throw new IOException("Already dispoased"); } return new ByteArrayInputStream(this.b); } public long length() { return this.b.length; } public void dispose() { this.dispoased = true; } } @Test public void testEntryUpdate() throws Exception { final HeapResourceFactory rf = new HeapResourceFactory() { @Override Resource createResource(final byte[] buf) { return new DisposableResource(buf); } }; impl = new BasicHttpCache(rf, backing, CacheConfig.DEFAULT); final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest origRequest = new HttpGet("http://foo.example.com/bar"); origRequest.setHeader("Accept-Encoding","gzip"); final HttpResponse origResponse = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); origResponse.setEntity(HttpTestUtils.makeBody(128)); origResponse.setHeader("Date", DateUtils.formatDate(new Date())); origResponse.setHeader("Cache-Control", "max-age=3600, public"); origResponse.setHeader("ETag", "\"etag\""); origResponse.setHeader("Vary", "Accept-Encoding"); origResponse.setHeader("Content-Encoding","gzip"); final HttpResponse response = impl.cacheAndReturnResponse( host, origRequest, origResponse, new Date(), new Date()); final HttpEntity entity = response.getEntity(); Assert.assertNotNull(entity); IOUtils.copyAndClose(entity.getContent(), new ByteArrayOutputStream()); } } ././@LongLink0100644 0000000 0000000 00000000175 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheableRequestPolicy.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCac0100644 0000000 0000000 00000006427 12301751715 032254 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.apache.http.message.BasicHttpRequest; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestCacheableRequestPolicy { private CacheableRequestPolicy policy; @Before public void setUp() throws Exception { policy = new CacheableRequestPolicy(); } @Test public void testIsGetServableFromCache() { final BasicHttpRequest request = new BasicHttpRequest("GET", "someUri"); Assert.assertTrue(policy.isServableFromCache(request)); } @Test public void testIsGetWithCacheControlServableFromCache() { BasicHttpRequest request = new BasicHttpRequest("GET", "someUri"); request.addHeader("Cache-Control", "no-cache"); Assert.assertFalse(policy.isServableFromCache(request)); request = new BasicHttpRequest("GET", "someUri"); request.addHeader("Cache-Control", "no-store"); request.addHeader("Cache-Control", "max-age=20"); Assert.assertFalse(policy.isServableFromCache(request)); request = new BasicHttpRequest("GET", "someUri"); request.addHeader("Cache-Control", "public"); request.addHeader("Cache-Control", "no-store, max-age=20"); Assert.assertFalse(policy.isServableFromCache(request)); } @Test public void testIsGetWithPragmaServableFromCache() { BasicHttpRequest request = new BasicHttpRequest("GET", "someUri"); request.addHeader("Pragma", "no-cache"); Assert.assertFalse(policy.isServableFromCache(request)); request = new BasicHttpRequest("GET", "someUri"); request.addHeader("Pragma", "value1"); request.addHeader("Pragma", "value2"); Assert.assertFalse(policy.isServableFromCache(request)); } @Test public void testIsArbitraryMethodServableFromCache() { BasicHttpRequest request = new BasicHttpRequest("HEAD", "someUri"); Assert.assertFalse(policy.isServableFromCache(request)); request = new BasicHttpRequest("get", "someUri"); Assert.assertFalse(policy.isServableFromCache(request)); } } ././@LongLink0100644 0000000 0000000 00000000202 12302131606 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCac0100644 0000000 0000000 00000013235 12301751715 032247 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.Date; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.utils.DateUtils; import org.apache.http.message.BasicHeader; import org.easymock.classextension.EasyMock; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestCachedHttpResponseGenerator { private HttpCacheEntry entry; private CacheValidityPolicy mockValidityPolicy; private CachedHttpResponseGenerator impl; private Date now; @Before public void setUp() { now = new Date(); final Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); final Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Date tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L); final Header[] hdrs = { new BasicHeader("Date", DateUtils.formatDate(eightSecondsAgo)), new BasicHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)), new BasicHeader("Content-Length", "150") }; entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, sixSecondsAgo, hdrs); mockValidityPolicy = EasyMock.createNiceMock(CacheValidityPolicy.class); impl = new CachedHttpResponseGenerator(mockValidityPolicy); } public void replayMocks() { EasyMock.replay(mockValidityPolicy); } @Test public void testResponseHasContentLength() { final byte[] buf = new byte[] { 1, 2, 3, 4, 5 }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(buf); final HttpResponse response = impl.generateResponse(entry); final Header length = response.getFirstHeader("Content-Length"); Assert.assertNotNull("Content-Length Header is missing", length); Assert.assertEquals("Content-Length does not match buffer length", buf.length, Integer .parseInt(length.getValue())); } @Test public void testContentLengthIsNotAddedWhenTransferEncodingIsPresent() { final Header[] hdrs = new Header[] { new BasicHeader("Transfer-Encoding", "chunked") }; final byte[] buf = new byte[] { 1, 2, 3, 4, 5 }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(hdrs, buf); final HttpResponse response = impl.generateResponse(entry); final Header length = response.getFirstHeader("Content-Length"); Assert.assertNull(length); } @Test public void testResponseMatchesCacheEntry() { final HttpResponse response = impl.generateResponse(entry); Assert.assertTrue(response.containsHeader("Content-Length")); Assert.assertSame("HTTP", response.getProtocolVersion().getProtocol()); Assert.assertEquals(1, response.getProtocolVersion().getMajor()); Assert.assertEquals(1, response.getProtocolVersion().getMinor()); } @Test public void testResponseStatusCodeMatchesCacheEntry() { final HttpResponse response = impl.generateResponse(entry); Assert.assertEquals(entry.getStatusCode(), response.getStatusLine().getStatusCode()); } @Test public void testAgeHeaderIsPopulatedWithCurrentAgeOfCacheEntryIfNonZero() { currentAge(10L); replayMocks(); final HttpResponse response = impl.generateResponse(entry); final Header ageHdr = response.getFirstHeader("Age"); Assert.assertNotNull(ageHdr); Assert.assertEquals(10L, Long.parseLong(ageHdr.getValue())); } @Test public void testAgeHeaderIsNotPopulatedIfCurrentAgeOfCacheEntryIsZero() { currentAge(0L); replayMocks(); final HttpResponse response = impl.generateResponse(entry); final Header ageHdr = response.getFirstHeader("Age"); Assert.assertNull(ageHdr); } @Test public void testAgeHeaderIsPopulatedWithMaxAgeIfCurrentAgeTooBig() { currentAge(CacheValidityPolicy.MAX_AGE + 1L); replayMocks(); final HttpResponse response = impl.generateResponse(entry); final Header ageHdr = response.getFirstHeader("Age"); Assert.assertNotNull(ageHdr); Assert.assertEquals(CacheValidityPolicy.MAX_AGE, Long.parseLong(ageHdr.getValue())); } private void currentAge(final long sec) { EasyMock.expect( mockValidityPolicy.getCurrentAgeSecs(EasyMock.same(entry), EasyMock.isA(Date.class))).andReturn(sec); } } ././@LongLink0100644 0000000 0000000 00000000207 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCac0100644 0000000 0000000 00000024404 12301751715 032247 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.Date; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpVersion; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.utils.DateUtils; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpRequest; import org.easymock.classextension.EasyMock; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestCachedResponseSuitabilityChecker { private Date now; private Date elevenSecondsAgo; private Date tenSecondsAgo; private Date nineSecondsAgo; private HttpHost host; private HttpRequest request; private HttpCacheEntry entry; private CacheValidityPolicy mockValidityPolicy; private CachedResponseSuitabilityChecker impl; @Before public void setUp() { now = new Date(); elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L); tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); host = new HttpHost("foo.example.com"); request = new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1); mockValidityPolicy = EasyMock.createNiceMock(CacheValidityPolicy.class); entry = HttpTestUtils.makeCacheEntry(); impl = new CachedResponseSuitabilityChecker(CacheConfig.DEFAULT); } private HttpCacheEntry getEntry(final Header[] headers) { return HttpTestUtils.makeCacheEntry(elevenSecondsAgo, nineSecondsAgo, headers); } public void replayMocks() { EasyMock.replay(mockValidityPolicy); } public void verifyMocks() { EasyMock.verify(mockValidityPolicy); } @Test public void testNotSuitableIfContentLengthHeaderIsWrong() { final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=3600"), new BasicHeader("Content-Length","1") }; entry = getEntry(headers); Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test public void testSuitableIfCacheEntryIsFresh() { final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=3600"), new BasicHeader("Content-Length","128") }; entry = getEntry(headers); Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test public void testNotSuitableIfCacheEntryIsNotFresh() { final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=5"), new BasicHeader("Content-Length","128") }; entry = getEntry(headers); Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test public void testNotSuitableIfRequestHasNoCache() { request.addHeader("Cache-Control", "no-cache"); final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=3600"), new BasicHeader("Content-Length","128") }; entry = getEntry(headers); Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test public void testNotSuitableIfAgeExceedsRequestMaxAge() { request.addHeader("Cache-Control", "max-age=10"); final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=3600"), new BasicHeader("Content-Length","128") }; entry = getEntry(headers); Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test public void testSuitableIfFreshAndAgeIsUnderRequestMaxAge() { request.addHeader("Cache-Control", "max-age=15"); final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=3600"), new BasicHeader("Content-Length","128") }; entry = getEntry(headers); Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test public void testSuitableIfFreshAndFreshnessLifetimeGreaterThanRequestMinFresh() { request.addHeader("Cache-Control", "min-fresh=10"); final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=3600"), new BasicHeader("Content-Length","128") }; entry = getEntry(headers); Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test public void testNotSuitableIfFreshnessLifetimeLessThanRequestMinFresh() { request.addHeader("Cache-Control", "min-fresh=10"); final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=15"), new BasicHeader("Content-Length","128") }; entry = getEntry(headers); Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test public void testSuitableEvenIfStaleButPermittedByRequestMaxStale() { request.addHeader("Cache-Control", "max-stale=10"); final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=5"), new BasicHeader("Content-Length","128") }; entry = getEntry(headers); Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test public void testNotSuitableIfStaleButTooStaleForRequestMaxStale() { request.addHeader("Cache-Control", "max-stale=2"); final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=5"), new BasicHeader("Content-Length","128") }; entry = getEntry(headers); Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test public void testMalformedCacheControlMaxAgeRequestHeaderCausesUnsuitableEntry() { request.addHeader(new BasicHeader("Cache-Control", "max-age=foo")); final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=3600"), new BasicHeader("Content-Length","128") }; entry = getEntry(headers); Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test public void testMalformedCacheControlMinFreshRequestHeaderCausesUnsuitableEntry() { request.addHeader(new BasicHeader("Cache-Control", "min-fresh=foo")); final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=3600"), new BasicHeader("Content-Length","128") }; entry = getEntry(headers); Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test public void testSuitableIfCacheEntryIsHeuristicallyFreshEnough() { final Date oneSecondAgo = new Date(now.getTime() - 1 * 1000L); final Date twentyOneSecondsAgo = new Date(now.getTime() - 21 * 1000L); final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(oneSecondAgo)), new BasicHeader("Last-Modified", DateUtils.formatDate(twentyOneSecondsAgo)), new BasicHeader("Content-Length", "128") }; entry = HttpTestUtils.makeCacheEntry(oneSecondAgo, oneSecondAgo, headers); final CacheConfig config = CacheConfig.custom() .setHeuristicCachingEnabled(true) .setHeuristicCoefficient(0.1f).build(); impl = new CachedResponseSuitabilityChecker(config); Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test public void testSuitableIfCacheEntryIsHeuristicallyFreshEnoughByDefault() { final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Content-Length", "128") }; entry = getEntry(headers); final CacheConfig config = CacheConfig.custom() .setHeuristicCachingEnabled(true) .setHeuristicDefaultLifetime(20) .build(); impl = new CachedResponseSuitabilityChecker(config); Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now)); } } ././@LongLink0100644 0000000 0000000 00000000170 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCac0100644 0000000 0000000 00000024201 12301751715 032242 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.fail; import java.io.IOException; import java.util.Date; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.utils.DateUtils; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpResponse; import org.junit.Before; import org.junit.Test; public class TestCacheEntryUpdater { private Date requestDate; private Date responseDate; private CacheEntryUpdater impl; private HttpCacheEntry entry; private Date now; private Date oneSecondAgo; private Date twoSecondsAgo; private Date eightSecondsAgo; private Date tenSecondsAgo; private HttpResponse response; @Before public void setUp() throws Exception { requestDate = new Date(System.currentTimeMillis() - 1000); responseDate = new Date(); now = new Date(); oneSecondAgo = new Date(now.getTime() - 1000L); twoSecondsAgo = new Date(now.getTime() - 2000L); eightSecondsAgo = new Date(now.getTime() - 8000L); tenSecondsAgo = new Date(now.getTime() - 10000L); response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); impl = new CacheEntryUpdater(); } @Test public void testUpdateCacheEntryReturnsDifferentEntryInstance() throws IOException { entry = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry newEntry = impl.updateCacheEntry(null, entry, requestDate, responseDate, response); assertNotSame(newEntry, entry); } @Test public void testHeadersAreMergedCorrectly() throws IOException { final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(responseDate)), new BasicHeader("ETag", "\"etag\"")}; entry = HttpTestUtils.makeCacheEntry(headers); response.setHeaders(new Header[]{}); final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, new Date(), new Date(), response); final Header[] updatedHeaders = updatedEntry.getAllHeaders(); assertEquals(2, updatedHeaders.length); headersContain(updatedHeaders, "Date", DateUtils.formatDate(responseDate)); headersContain(updatedHeaders, "ETag", "\"etag\""); } @Test public void testNewerHeadersReplaceExistingHeaders() throws IOException { final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(requestDate)), new BasicHeader("Cache-Control", "private"), new BasicHeader("ETag", "\"etag\""), new BasicHeader("Last-Modified", DateUtils.formatDate(requestDate)), new BasicHeader("Cache-Control", "max-age=0"),}; entry = HttpTestUtils.makeCacheEntry(headers); response.setHeaders(new Header[] { new BasicHeader("Last-Modified", DateUtils.formatDate(responseDate)), new BasicHeader("Cache-Control", "public")}); final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, new Date(), new Date(), response); final Header[] updatedHeaders = updatedEntry.getAllHeaders(); assertEquals(4, updatedHeaders.length); headersContain(updatedHeaders, "Date", DateUtils.formatDate(requestDate)); headersContain(updatedHeaders, "ETag", "\"etag\""); headersContain(updatedHeaders, "Last-Modified", DateUtils.formatDate(responseDate)); headersContain(updatedHeaders, "Cache-Control", "public"); } @Test public void testNewHeadersAreAddedByMerge() throws IOException { final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(requestDate)), new BasicHeader("ETag", "\"etag\"")}; entry = HttpTestUtils.makeCacheEntry(headers); response.setHeaders(new Header[]{ new BasicHeader("Last-Modified", DateUtils.formatDate(responseDate)), new BasicHeader("Cache-Control", "public"),}); final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, new Date(), new Date(), response); final Header[] updatedHeaders = updatedEntry.getAllHeaders(); assertEquals(4, updatedHeaders.length); headersContain(updatedHeaders, "Date", DateUtils.formatDate(requestDate)); headersContain(updatedHeaders, "ETag", "\"etag\""); headersContain(updatedHeaders, "Last-Modified", DateUtils.formatDate(responseDate)); headersContain(updatedHeaders, "Cache-Control", "public"); } @Test public void oldHeadersRetainedIfResponseOlderThanEntry() throws Exception { final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(oneSecondAgo)), new BasicHeader("ETag", "\"new-etag\"") }; entry = HttpTestUtils.makeCacheEntry(twoSecondsAgo, now, headers); response.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); response.setHeader("ETag", "\"old-etag\""); final HttpCacheEntry result = impl.updateCacheEntry("A", entry, new Date(), new Date(), response); assertEquals(2, result.getAllHeaders().length); headersContain(result.getAllHeaders(), "Date", DateUtils.formatDate(oneSecondAgo)); headersContain(result.getAllHeaders(), "ETag", "\"new-etag\""); } @Test public void testUpdatedEntryHasLatestRequestAndResponseDates() throws IOException { entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo); final HttpCacheEntry updated = impl.updateCacheEntry(null, entry, twoSecondsAgo, oneSecondAgo, response); assertEquals(twoSecondsAgo, updated.getRequestDate()); assertEquals(oneSecondAgo, updated.getResponseDate()); } @Test public void entry1xxWarningsAreRemovedOnUpdate() throws Exception { final Header[] headers = { new BasicHeader("Warning", "110 fred \"Response is stale\""), new BasicHeader("ETag", "\"old\""), new BasicHeader("Date", DateUtils.formatDate(eightSecondsAgo)) }; entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, headers); response.setHeader("ETag", "\"new\""); response.setHeader("Date", DateUtils.formatDate(twoSecondsAgo)); final HttpCacheEntry updated = impl.updateCacheEntry(null, entry, twoSecondsAgo, oneSecondAgo, response); assertEquals(0, updated.getHeaders("Warning").length); } @Test public void entryWithMalformedDateIsStillUpdated() throws Exception { final Header[] headers = { new BasicHeader("ETag", "\"old\""), new BasicHeader("Date", "bad-date") }; entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, headers); response.setHeader("ETag", "\"new\""); response.setHeader("Date", DateUtils.formatDate(twoSecondsAgo)); final HttpCacheEntry updated = impl.updateCacheEntry(null, entry, twoSecondsAgo, oneSecondAgo, response); assertEquals("\"new\"", updated.getFirstHeader("ETag").getValue()); } @Test public void entryIsStillUpdatedByResponseWithMalformedDate() throws Exception { final Header[] headers = { new BasicHeader("ETag", "\"old\""), new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)) }; entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, headers); response.setHeader("ETag", "\"new\""); response.setHeader("Date", "bad-date"); final HttpCacheEntry updated = impl.updateCacheEntry(null, entry, twoSecondsAgo, oneSecondAgo, response); assertEquals("\"new\"", updated.getFirstHeader("ETag").getValue()); } @Test public void cannotUpdateFromANon304OriginResponse() throws Exception { entry = HttpTestUtils.makeCacheEntry(); response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); try { impl.updateCacheEntry("A", entry, new Date(), new Date(), response); fail("should have thrown exception"); } catch (final IllegalArgumentException expected) { } } private void headersContain(final Header[] headers, final String name, final String value) { for (final Header header : headers) { if (header.getName().equals(name)) { if (header.getValue().equals(value)) { return; } } } fail("Header [" + name + ": " + value + "] not found in headers."); } } ././@LongLink0100644 0000000 0000000 00000000167 12302131606 011631 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheInvalidator.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCac0100644 0000000 0000000 00000055375 12301751714 032261 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import static org.easymock.EasyMock.expect; import static org.easymock.classextension.EasyMock.createNiceMock; import static org.easymock.classextension.EasyMock.replay; import static org.easymock.classextension.EasyMock.verify; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.http.Header; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.ProtocolVersion; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.client.utils.DateUtils; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpEntityEnclosingRequest; import org.apache.http.message.BasicHttpRequest; import org.apache.http.message.BasicHttpResponse; import org.easymock.EasyMock; import org.easymock.IAnswer; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestCacheInvalidator { private static final ProtocolVersion HTTP_1_1 = new ProtocolVersion("HTTP", 1, 1); private CacheInvalidator impl; private HttpCacheStorage mockStorage; private HttpHost host; private CacheKeyGenerator cacheKeyGenerator; private HttpCacheEntry mockEntry; private HttpRequest request; private HttpResponse response; private Date now; private Date tenSecondsAgo; @Before public void setUp() { now = new Date(); tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); host = new HttpHost("foo.example.com"); mockStorage = createNiceMock(HttpCacheStorage.class); cacheKeyGenerator = new CacheKeyGenerator(); mockEntry = createNiceMock(HttpCacheEntry.class); request = HttpTestUtils.makeDefaultRequest(); response = HttpTestUtils.make200Response(); impl = new CacheInvalidator(cacheKeyGenerator, mockStorage); } private void replayMocks() { replay(mockStorage); replay(mockEntry); } private void verifyMocks() { verify(mockStorage); verify(mockEntry); } // Tests @Test public void testInvalidatesRequestsThatArentGETorHEAD() throws Exception { request = new BasicHttpRequest("POST","/path", HTTP_1_1); final String theUri = "http://foo.example.com:80/path"; final Map variantMap = new HashMap(); cacheEntryHasVariantMap(variantMap); cacheReturnsEntryForUri(theUri); entryIsRemoved(theUri); replayMocks(); impl.flushInvalidatedCacheEntries(host, request); verifyMocks(); } @Test public void testInvalidatesUrisInContentLocationHeadersOnPUTs() throws Exception { final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("PUT","/",HTTP_1_1); request.setEntity(HttpTestUtils.makeBody(128)); request.setHeader("Content-Length","128"); final String contentLocation = "http://foo.example.com/content"; request.setHeader("Content-Location", contentLocation); final String theUri = "http://foo.example.com:80/"; cacheEntryHasVariantMap(new HashMap()); cacheReturnsEntryForUri(theUri); entryIsRemoved(theUri); entryIsRemoved("http://foo.example.com:80/content"); replayMocks(); impl.flushInvalidatedCacheEntries(host, request); verifyMocks(); } @Test public void testInvalidatesUrisInLocationHeadersOnPUTs() throws Exception { final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("PUT","/",HTTP_1_1); request.setEntity(HttpTestUtils.makeBody(128)); request.setHeader("Content-Length","128"); final String contentLocation = "http://foo.example.com/content"; request.setHeader("Location",contentLocation); final String theUri = "http://foo.example.com:80/"; cacheEntryHasVariantMap(new HashMap()); cacheReturnsEntryForUri(theUri); entryIsRemoved(theUri); entryIsRemoved(cacheKeyGenerator.canonicalizeUri(contentLocation)); replayMocks(); impl.flushInvalidatedCacheEntries(host, request); verifyMocks(); } @Test public void testInvalidatesRelativeUrisInContentLocationHeadersOnPUTs() throws Exception { final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("PUT","/",HTTP_1_1); request.setEntity(HttpTestUtils.makeBody(128)); request.setHeader("Content-Length","128"); final String relativePath = "/content"; request.setHeader("Content-Location",relativePath); final String theUri = "http://foo.example.com:80/"; cacheEntryHasVariantMap(new HashMap()); cacheReturnsEntryForUri(theUri); entryIsRemoved(theUri); entryIsRemoved("http://foo.example.com:80/content"); replayMocks(); impl.flushInvalidatedCacheEntries(host, request); verifyMocks(); } @Test public void testDoesNotInvalidateUrisInContentLocationHeadersOnPUTsToDifferentHosts() throws Exception { final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("PUT","/",HTTP_1_1); request.setEntity(HttpTestUtils.makeBody(128)); request.setHeader("Content-Length","128"); final String contentLocation = "http://bar.example.com/content"; request.setHeader("Content-Location",contentLocation); final String theUri = "http://foo.example.com:80/"; cacheEntryHasVariantMap(new HashMap()); cacheReturnsEntryForUri(theUri); entryIsRemoved(theUri); replayMocks(); impl.flushInvalidatedCacheEntries(host, request); verifyMocks(); } @Test public void testDoesNotInvalidateGETRequest() throws Exception { request = new BasicHttpRequest("GET","/",HTTP_1_1); replayMocks(); impl.flushInvalidatedCacheEntries(host, request); verifyMocks(); } @Test public void testDoesNotInvalidateHEADRequest() throws Exception { request = new BasicHttpRequest("HEAD","/",HTTP_1_1); replayMocks(); impl.flushInvalidatedCacheEntries(host, request); verifyMocks(); } @Test public void testDoesNotInvalidateRequestsWithClientCacheControlHeaders() throws Exception { request = new BasicHttpRequest("GET","/",HTTP_1_1); request.setHeader("Cache-Control","no-cache"); replayMocks(); impl.flushInvalidatedCacheEntries(host, request); verifyMocks(); } @Test public void testDoesNotInvalidateRequestsWithClientPragmaHeaders() throws Exception { request = new BasicHttpRequest("GET","/",HTTP_1_1); request.setHeader("Pragma","no-cache"); replayMocks(); impl.flushInvalidatedCacheEntries(host, request); verifyMocks(); } @Test public void testVariantURIsAreFlushedAlso() throws Exception { request = new BasicHttpRequest("POST","/",HTTP_1_1); final String theUri = "http://foo.example.com:80/"; final String variantUri = "theVariantURI"; final Map mapOfURIs = new HashMap(); mapOfURIs.put(variantUri,variantUri); cacheReturnsEntryForUri(theUri); cacheEntryHasVariantMap(mapOfURIs); entryIsRemoved(variantUri); entryIsRemoved(theUri); replayMocks(); impl.flushInvalidatedCacheEntries(host, request); verifyMocks(); } @Test public void testCacheFlushException() throws Exception { request = new BasicHttpRequest("POST","/",HTTP_1_1); final String theURI = "http://foo.example.com:80/"; cacheReturnsExceptionForUri(theURI); replayMocks(); impl.flushInvalidatedCacheEntries(host, request); verifyMocks(); } @Test public void doesNotFlushForResponsesWithoutContentLocation() throws Exception { replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void flushesEntryIfFresherAndSpecifiedByContentLocation() throws Exception { response.setHeader("ETag","\"new-etag\""); response.setHeader("Date", DateUtils.formatDate(now)); final String theURI = "http://foo.example.com:80/bar"; response.setHeader("Content-Location", theURI); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("ETag", "\"old-etag\"") }); expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes(); mockStorage.removeEntry(theURI); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void flushesEntryIfFresherAndSpecifiedByLocation() throws Exception { response.setStatusCode(201); response.setHeader("ETag","\"new-etag\""); response.setHeader("Date", DateUtils.formatDate(now)); final String theURI = "http://foo.example.com:80/bar"; response.setHeader("Location", theURI); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("ETag", "\"old-etag\"") }); expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes(); mockStorage.removeEntry(theURI); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void doesNotFlushEntryForUnsuccessfulResponse() throws Exception { response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_BAD_REQUEST, "Bad Request"); response.setHeader("ETag","\"new-etag\""); response.setHeader("Date", DateUtils.formatDate(now)); final String theURI = "http://foo.example.com:80/bar"; response.setHeader("Content-Location", theURI); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("ETag", "\"old-etag\"") }); expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes(); mockStorage.removeEntry(theURI); EasyMock.expectLastCall().andAnswer(new IAnswer() { public Void answer() { Assert.fail(); return null; } }).anyTimes(); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void flushesEntryIfFresherAndSpecifiedByNonCanonicalContentLocation() throws Exception { response.setHeader("ETag","\"new-etag\""); response.setHeader("Date", DateUtils.formatDate(now)); final String cacheKey = "http://foo.example.com:80/bar"; response.setHeader("Content-Location", "http://foo.example.com/bar"); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("ETag", "\"old-etag\"") }); expect(mockStorage.getEntry(cacheKey)).andReturn(entry).anyTimes(); mockStorage.removeEntry(cacheKey); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void flushesEntryIfFresherAndSpecifiedByRelativeContentLocation() throws Exception { response.setHeader("ETag","\"new-etag\""); response.setHeader("Date", DateUtils.formatDate(now)); final String cacheKey = "http://foo.example.com:80/bar"; response.setHeader("Content-Location", "/bar"); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("ETag", "\"old-etag\"") }); expect(mockStorage.getEntry(cacheKey)).andReturn(entry).anyTimes(); mockStorage.removeEntry(cacheKey); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void doesNotFlushEntryIfContentLocationFromDifferentHost() throws Exception { response.setHeader("ETag","\"new-etag\""); response.setHeader("Date", DateUtils.formatDate(now)); final String cacheKey = "http://baz.example.com:80/bar"; response.setHeader("Content-Location", cacheKey); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("ETag", "\"old-etag\"") }); expect(mockStorage.getEntry(cacheKey)).andReturn(entry).anyTimes(); mockStorage.removeEntry(cacheKey); EasyMock.expectLastCall().andAnswer(new IAnswer() { public Void answer() { Assert.fail(); return null; } }).anyTimes(); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void doesNotFlushEntrySpecifiedByContentLocationIfEtagsMatch() throws Exception { response.setHeader("ETag","\"same-etag\""); response.setHeader("Date", DateUtils.formatDate(now)); final String theURI = "http://foo.example.com:80/bar"; response.setHeader("Content-Location", theURI); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("ETag", "\"same-etag\"") }); expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes(); mockStorage.removeEntry(theURI); EasyMock.expectLastCall().andAnswer(new IAnswer() { public Void answer() { Assert.fail(); return null; } }).anyTimes(); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void doesNotFlushEntrySpecifiedByContentLocationIfOlder() throws Exception { response.setHeader("ETag","\"new-etag\""); response.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); final String theURI = "http://foo.example.com:80/bar"; response.setHeader("Content-Location", theURI); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("Date", DateUtils.formatDate(now)), new BasicHeader("ETag", "\"old-etag\"") }); expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes(); mockStorage.removeEntry(theURI); EasyMock.expectLastCall().andAnswer(new IAnswer() { public Void answer() { Assert.fail(); return null; } }).anyTimes(); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void doesNotFlushEntryIfNotInCache() throws Exception { response.setHeader("ETag","\"new-etag\""); response.setHeader("Date", DateUtils.formatDate(now)); final String theURI = "http://foo.example.com:80/bar"; response.setHeader("Content-Location", theURI); expect(mockStorage.getEntry(theURI)).andReturn(null).anyTimes(); mockStorage.removeEntry(theURI); EasyMock.expectLastCall().andAnswer(new IAnswer() { public Void answer() { Assert.fail(); return null; } }).anyTimes(); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void doesNotFlushEntrySpecifiedByContentLocationIfResponseHasNoEtag() throws Exception { response.removeHeaders("ETag"); response.setHeader("Date", DateUtils.formatDate(now)); final String theURI = "http://foo.example.com:80/bar"; response.setHeader("Content-Location", theURI); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("ETag", "\"old-etag\"") }); expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes(); mockStorage.removeEntry(theURI); EasyMock.expectLastCall().andAnswer(new IAnswer() { public Void answer() { Assert.fail(); return null; } }).anyTimes(); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void doesNotFlushEntrySpecifiedByContentLocationIfEntryHasNoEtag() throws Exception { response.setHeader("ETag", "\"some-etag\""); response.setHeader("Date", DateUtils.formatDate(now)); final String theURI = "http://foo.example.com:80/bar"; response.setHeader("Content-Location", theURI); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), }); expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes(); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void flushesEntrySpecifiedByContentLocationIfResponseHasNoDate() throws Exception { response.setHeader("ETag", "\"new-etag\""); response.removeHeaders("Date"); final String theURI = "http://foo.example.com:80/bar"; response.setHeader("Content-Location", theURI); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("ETag", "\"old-etag\""), new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), }); expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes(); mockStorage.removeEntry(theURI); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void flushesEntrySpecifiedByContentLocationIfEntryHasNoDate() throws Exception { response.setHeader("ETag","\"new-etag\""); response.setHeader("Date", DateUtils.formatDate(now)); final String theURI = "http://foo.example.com:80/bar"; response.setHeader("Content-Location", theURI); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("ETag", "\"old-etag\"") }); expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes(); mockStorage.removeEntry(theURI); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void flushesEntrySpecifiedByContentLocationIfResponseHasMalformedDate() throws Exception { response.setHeader("ETag","\"new-etag\""); response.setHeader("Date", "blarg"); final String theURI = "http://foo.example.com:80/bar"; response.setHeader("Content-Location", theURI); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("ETag", "\"old-etag\""), new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)) }); expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes(); mockStorage.removeEntry(theURI); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } @Test public void flushesEntrySpecifiedByContentLocationIfEntryHasMalformedDate() throws Exception { response.setHeader("ETag","\"new-etag\""); response.setHeader("Date", DateUtils.formatDate(now)); final String theURI = "http://foo.example.com:80/bar"; response.setHeader("Content-Location", theURI); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("ETag", "\"old-etag\""), new BasicHeader("Date", "foo") }); expect(mockStorage.getEntry(theURI)).andReturn(entry).anyTimes(); mockStorage.removeEntry(theURI); replayMocks(); impl.flushInvalidatedCacheEntries(host, request, response); verifyMocks(); } // Expectations private void cacheEntryHasVariantMap(final Map variantMap) { expect(mockEntry.getVariantMap()).andReturn(variantMap); } private void cacheReturnsEntryForUri(final String theUri) throws IOException { expect(mockStorage.getEntry(theUri)).andReturn(mockEntry); } private void cacheReturnsExceptionForUri(final String theUri) throws IOException { expect(mockStorage.getEntry(theUri)).andThrow( new IOException("TOTAL FAIL")); } private void entryIsRemoved(final String theUri) throws IOException { mockStorage.removeEntry(theUri); } } ././@LongLink0100644 0000000 0000000 00000000170 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheKeyGenerator.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCac0100644 0000000 0000000 00000045377 12301751715 032263 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpVersion; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.methods.HttpGet; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpRequest; import org.easymock.classextension.EasyMock; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestCacheKeyGenerator { private static final BasicHttpRequest REQUEST_FULL_EPISODES = new BasicHttpRequest("GET", "/full_episodes"); private static final BasicHttpRequest REQUEST_ROOT = new BasicHttpRequest("GET", "/"); CacheKeyGenerator extractor; private HttpHost host; private HttpCacheEntry mockEntry; private HttpRequest mockRequest; @Before public void setUp() throws Exception { host = new HttpHost("foo.example.com"); mockEntry = EasyMock.createNiceMock(HttpCacheEntry.class); mockRequest = EasyMock.createNiceMock(HttpRequest.class); extractor = new CacheKeyGenerator(); } private void replayMocks() { EasyMock.replay(mockEntry); EasyMock.replay(mockRequest); } private void verifyMocks() { EasyMock.verify(mockEntry); EasyMock.verify(mockRequest); } @Test public void testExtractsUriFromAbsoluteUriInRequest() { final HttpHost host = new HttpHost("bar.example.com"); final HttpRequest req = new HttpGet("http://foo.example.com/"); Assert.assertEquals("http://foo.example.com:80/", extractor.getURI(host, req)); } @Test public void testGetURIWithDefaultPortAndScheme() { Assert.assertEquals("http://www.comcast.net:80/", extractor.getURI(new HttpHost( "www.comcast.net"), REQUEST_ROOT)); Assert.assertEquals("http://www.fancast.com:80/full_episodes", extractor.getURI(new HttpHost( "www.fancast.com"), REQUEST_FULL_EPISODES)); } @Test public void testGetURIWithDifferentScheme() { Assert.assertEquals("https://www.comcast.net:443/", extractor.getURI(new HttpHost( "www.comcast.net", -1, "https"), REQUEST_ROOT)); Assert.assertEquals("myhttp://www.fancast.com/full_episodes", extractor.getURI( new HttpHost("www.fancast.com", -1, "myhttp"), REQUEST_FULL_EPISODES)); } @Test public void testGetURIWithDifferentPort() { Assert.assertEquals("http://www.comcast.net:8080/", extractor.getURI(new HttpHost( "www.comcast.net", 8080), REQUEST_ROOT)); Assert.assertEquals("http://www.fancast.com:9999/full_episodes", extractor.getURI( new HttpHost("www.fancast.com", 9999), REQUEST_FULL_EPISODES)); } @Test public void testGetURIWithDifferentPortAndScheme() { Assert.assertEquals("https://www.comcast.net:8080/", extractor.getURI(new HttpHost( "www.comcast.net", 8080, "https"), REQUEST_ROOT)); Assert.assertEquals("myhttp://www.fancast.com:9999/full_episodes", extractor.getURI( new HttpHost("www.fancast.com", 9999, "myhttp"), REQUEST_FULL_EPISODES)); } @Test public void testGetURIWithQueryParameters() { Assert.assertEquals("http://www.comcast.net:80/?foo=bar", extractor.getURI(new HttpHost( "www.comcast.net", -1, "http"), new BasicHttpRequest("GET", "/?foo=bar"))); Assert.assertEquals("http://www.fancast.com:80/full_episodes?foo=bar", extractor.getURI( new HttpHost("www.fancast.com", -1, "http"), new BasicHttpRequest("GET", "/full_episodes?foo=bar"))); } @Test public void testGetVariantURIWithNoVaryHeaderReturnsNormalURI() { final String theURI = "theURI"; org.easymock.EasyMock.expect(mockEntry.hasVariants()).andReturn(false); extractor = new CacheKeyGenerator() { @Override public String getURI(final HttpHost h, final HttpRequest req) { Assert.assertSame(host, h); Assert.assertSame(mockRequest, req); return theURI; } }; replayMocks(); final String result = extractor.getVariantURI(host, mockRequest, mockEntry); verifyMocks(); Assert.assertSame(theURI, result); } @Test public void testGetVariantURIWithSingleValueVaryHeaderPrepends() { final String theURI = "theURI"; final Header[] varyHeaders = { new BasicHeader("Vary", "Accept-Encoding") }; final Header[] encHeaders = { new BasicHeader("Accept-Encoding", "gzip") }; extractor = new CacheKeyGenerator() { @Override public String getURI(final HttpHost h, final HttpRequest req) { Assert.assertSame(host, h); Assert.assertSame(mockRequest, req); return theURI; } }; EasyMock.expect(mockEntry.hasVariants()).andReturn(true).anyTimes(); EasyMock.expect(mockEntry.getHeaders("Vary")).andReturn(varyHeaders); EasyMock.expect(mockRequest.getHeaders("Accept-Encoding")).andReturn( encHeaders); replayMocks(); final String result = extractor.getVariantURI(host, mockRequest, mockEntry); verifyMocks(); Assert.assertEquals("{Accept-Encoding=gzip}" + theURI, result); } @Test public void testGetVariantURIWithMissingRequestHeader() { final String theURI = "theURI"; final Header[] noHeaders = new Header[0]; final Header[] varyHeaders = { new BasicHeader("Vary", "Accept-Encoding") }; extractor = new CacheKeyGenerator() { @Override public String getURI(final HttpHost h, final HttpRequest req) { Assert.assertSame(host, h); Assert.assertSame(mockRequest, req); return theURI; } }; EasyMock.expect(mockEntry.hasVariants()).andReturn(true).anyTimes(); EasyMock.expect(mockEntry.getHeaders("Vary")).andReturn(varyHeaders); EasyMock.expect(mockRequest.getHeaders("Accept-Encoding")) .andReturn(noHeaders); replayMocks(); final String result = extractor.getVariantURI(host, mockRequest, mockEntry); verifyMocks(); Assert.assertEquals("{Accept-Encoding=}" + theURI, result); } @Test public void testGetVariantURIAlphabetizesWithMultipleVaryingHeaders() { final String theURI = "theURI"; final Header[] varyHeaders = { new BasicHeader("Vary", "User-Agent, Accept-Encoding") }; final Header[] encHeaders = { new BasicHeader("Accept-Encoding", "gzip") }; final Header[] uaHeaders = { new BasicHeader("User-Agent", "browser") }; extractor = new CacheKeyGenerator() { @Override public String getURI(final HttpHost h, final HttpRequest req) { Assert.assertSame(host, h); Assert.assertSame(mockRequest, req); return theURI; } }; EasyMock.expect(mockEntry.hasVariants()).andReturn(true).anyTimes(); EasyMock.expect(mockEntry.getHeaders("Vary")).andReturn(varyHeaders); EasyMock.expect(mockRequest.getHeaders("Accept-Encoding")).andReturn( encHeaders); EasyMock.expect(mockRequest.getHeaders("User-Agent")).andReturn(uaHeaders); replayMocks(); final String result = extractor.getVariantURI(host, mockRequest, mockEntry); verifyMocks(); Assert.assertEquals("{Accept-Encoding=gzip&User-Agent=browser}" + theURI, result); } @Test public void testGetVariantURIHandlesMultipleVaryHeaders() { final String theURI = "theURI"; final Header[] varyHeaders = { new BasicHeader("Vary", "User-Agent"), new BasicHeader("Vary", "Accept-Encoding") }; final Header[] encHeaders = { new BasicHeader("Accept-Encoding", "gzip") }; final Header[] uaHeaders = { new BasicHeader("User-Agent", "browser") }; extractor = new CacheKeyGenerator() { @Override public String getURI(final HttpHost h, final HttpRequest req) { Assert.assertSame(host, h); Assert.assertSame(mockRequest, req); return theURI; } }; EasyMock.expect(mockEntry.hasVariants()).andReturn(true).anyTimes(); EasyMock.expect(mockEntry.getHeaders("Vary")).andReturn(varyHeaders); EasyMock.expect(mockRequest.getHeaders("Accept-Encoding")).andReturn(encHeaders); EasyMock.expect(mockRequest.getHeaders("User-Agent")).andReturn(uaHeaders); replayMocks(); final String result = extractor.getVariantURI(host, mockRequest, mockEntry); verifyMocks(); Assert.assertEquals("{Accept-Encoding=gzip&User-Agent=browser}" + theURI, result); } @Test public void testGetVariantURIHandlesMultipleLineRequestHeaders() { final String theURI = "theURI"; final Header[] varyHeaders = { new BasicHeader("Vary", "User-Agent, Accept-Encoding") }; final Header[] encHeaders = { new BasicHeader("Accept-Encoding", "gzip"), new BasicHeader("Accept-Encoding", "deflate") }; final Header[] uaHeaders = { new BasicHeader("User-Agent", "browser") }; extractor = new CacheKeyGenerator() { @Override public String getURI(final HttpHost h, final HttpRequest req) { Assert.assertSame(host, h); Assert.assertSame(mockRequest, req); return theURI; } }; EasyMock.expect(mockEntry.hasVariants()).andReturn(true).anyTimes(); EasyMock.expect(mockEntry.getHeaders("Vary")).andReturn(varyHeaders); EasyMock.expect(mockRequest.getHeaders("Accept-Encoding")).andReturn(encHeaders); EasyMock.expect(mockRequest.getHeaders("User-Agent")).andReturn(uaHeaders); replayMocks(); final String result = extractor.getVariantURI(host, mockRequest, mockEntry); verifyMocks(); Assert .assertEquals("{Accept-Encoding=gzip%2C+deflate&User-Agent=browser}" + theURI, result); } /* * "When comparing two URIs to decide if they match or not, a client * SHOULD use a case-sensitive octet-by-octet comparison of the entire * URIs, with these exceptions: * - A port that is empty or not given is equivalent to the default * port for that URI-reference; * - Comparisons of host names MUST be case-insensitive; * - Comparisons of scheme names MUST be case-insensitive; * - An empty abs_path is equivalent to an abs_path of "/". * Characters other than those in the 'reserved' and 'unsafe' sets * (see RFC 2396 [42]) are equivalent to their '"%" HEX HEX' encoding." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.2.3 */ @Test public void testEmptyPortEquivalentToDefaultPortForHttp() { final HttpHost host1 = new HttpHost("foo.example.com:"); final HttpHost host2 = new HttpHost("foo.example.com:80"); final HttpRequest req = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); Assert.assertEquals(extractor.getURI(host1, req), extractor.getURI(host2, req)); } @Test public void testEmptyPortEquivalentToDefaultPortForHttps() { final HttpHost host1 = new HttpHost("foo.example.com", -1, "https"); final HttpHost host2 = new HttpHost("foo.example.com", 443, "https"); final HttpRequest req = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); final String uri1 = extractor.getURI(host1, req); final String uri2 = extractor.getURI(host2, req); Assert.assertEquals(uri1, uri2); } @Test public void testEmptyPortEquivalentToDefaultPortForHttpsAbsoluteURI() { final HttpHost host = new HttpHost("foo.example.com", -1, "https"); final HttpGet get1 = new HttpGet("https://bar.example.com:/"); final HttpGet get2 = new HttpGet("https://bar.example.com:443/"); final String uri1 = extractor.getURI(host, get1); final String uri2 = extractor.getURI(host, get2); Assert.assertEquals(uri1, uri2); } @Test public void testNotProvidedPortEquivalentToDefaultPortForHttpsAbsoluteURI() { final HttpHost host = new HttpHost("foo.example.com", -1, "https"); final HttpGet get1 = new HttpGet("https://bar.example.com/"); final HttpGet get2 = new HttpGet("https://bar.example.com:443/"); final String uri1 = extractor.getURI(host, get1); final String uri2 = extractor.getURI(host, get2); Assert.assertEquals(uri1, uri2); } @Test public void testNotProvidedPortEquivalentToDefaultPortForHttp() { final HttpHost host1 = new HttpHost("foo.example.com"); final HttpHost host2 = new HttpHost("foo.example.com:80"); final HttpRequest req = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); Assert.assertEquals(extractor.getURI(host1, req), extractor.getURI(host2, req)); } @Test public void testHostNameComparisonsAreCaseInsensitive() { final HttpHost host1 = new HttpHost("foo.example.com"); final HttpHost host2 = new HttpHost("FOO.EXAMPLE.COM"); final HttpRequest req = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); Assert.assertEquals(extractor.getURI(host1, req), extractor.getURI(host2, req)); } @Test public void testSchemeNameComparisonsAreCaseInsensitive() { final HttpHost host1 = new HttpHost("foo.example.com", -1, "http"); final HttpHost host2 = new HttpHost("foo.example.com", -1, "HTTP"); final HttpRequest req = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); Assert.assertEquals(extractor.getURI(host1, req), extractor.getURI(host2, req)); } @Test public void testEmptyAbsPathIsEquivalentToSlash() { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); final HttpRequest req2 = new HttpGet("http://foo.example.com"); Assert.assertEquals(extractor.getURI(host, req1), extractor.getURI(host, req2)); } @Test public void testExtraDotSegmentsAreIgnored() { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); final HttpRequest req2 = new HttpGet("http://foo.example.com/./"); Assert.assertEquals(extractor.getURI(host, req1), extractor.getURI(host, req2)); } @Test public void testExtraDotDotSegmentsAreIgnored() { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req1 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); final HttpRequest req2 = new HttpGet("http://foo.example.com/.././../"); Assert.assertEquals(extractor.getURI(host, req1), extractor.getURI(host, req2)); } @Test public void testIntermidateDotDotSegementsAreEquivalent() { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req1 = new BasicHttpRequest("GET", "/home.html", HttpVersion.HTTP_1_1); final HttpRequest req2 = new BasicHttpRequest("GET", "/%7Esmith/../home.html", HttpVersion.HTTP_1_1); Assert.assertEquals(extractor.getURI(host, req1), extractor.getURI(host, req2)); } @Test public void testIntermidateEncodedDotDotSegementsAreEquivalent() { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req1 = new BasicHttpRequest("GET", "/home.html", HttpVersion.HTTP_1_1); final HttpRequest req2 = new BasicHttpRequest("GET", "/%7Esmith%2F../home.html", HttpVersion.HTTP_1_1); Assert.assertEquals(extractor.getURI(host, req1), extractor.getURI(host, req2)); } @Test public void testIntermidateDotSegementsAreEquivalent() { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req1 = new BasicHttpRequest("GET", "/~smith/home.html", HttpVersion.HTTP_1_1); final HttpRequest req2 = new BasicHttpRequest("GET", "/%7Esmith/./home.html", HttpVersion.HTTP_1_1); Assert.assertEquals(extractor.getURI(host, req1), extractor.getURI(host, req2)); } @Test public void testEquivalentPathEncodingsAreEquivalent() { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req1 = new BasicHttpRequest("GET", "/~smith/home.html", HttpVersion.HTTP_1_1); final HttpRequest req2 = new BasicHttpRequest("GET", "/%7Esmith/home.html", HttpVersion.HTTP_1_1); Assert.assertEquals(extractor.getURI(host, req1), extractor.getURI(host, req2)); } @Test public void testEquivalentExtraPathEncodingsAreEquivalent() { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req1 = new BasicHttpRequest("GET", "/~smith/home.html", HttpVersion.HTTP_1_1); final HttpRequest req2 = new BasicHttpRequest("GET", "/%7Esmith%2Fhome.html", HttpVersion.HTTP_1_1); Assert.assertEquals(extractor.getURI(host, req1), extractor.getURI(host, req2)); } @Test public void testEquivalentExtraPathEncodingsWithPercentAreEquivalent() { final HttpHost host = new HttpHost("foo.example.com"); final HttpRequest req1 = new BasicHttpRequest("GET", "/~smith/home%20folder.html", HttpVersion.HTTP_1_1); final HttpRequest req2 = new BasicHttpRequest("GET", "/%7Esmith%2Fhome%20folder.html", HttpVersion.HTTP_1_1); Assert.assertEquals(extractor.getURI(host, req1), extractor.getURI(host, req2)); } } ././@LongLink0100644 0000000 0000000 00000000172 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCac0100644 0000000 0000000 00000053014 12301751713 032244 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.util.Date; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.HttpVersion; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.utils.DateUtils; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.HTTP; import org.junit.Before; import org.junit.Test; public class TestCacheValidityPolicy { private CacheValidityPolicy impl; private Date now; private Date oneSecondAgo; private Date sixSecondsAgo; private Date tenSecondsAgo; private Date elevenSecondsAgo; @Before public void setUp() { impl = new CacheValidityPolicy(); now = new Date(); oneSecondAgo = new Date(now.getTime() - 1 * 1000L); sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L); } @Test public void testApparentAgeIsMaxIntIfDateHeaderNotPresent() { final Header[] headers = { new BasicHeader("Server", "MockServer/1.0") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertEquals(2147483648L, impl.getApparentAgeSecs(entry)); } @Test public void testApparentAgeIsResponseReceivedTimeLessDateHeader() { final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils .formatDate(tenSecondsAgo)) }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, sixSecondsAgo, headers); assertEquals(4, impl.getApparentAgeSecs(entry)); } @Test public void testNegativeApparentAgeIsBroughtUpToZero() { final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils .formatDate(sixSecondsAgo)) }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now,tenSecondsAgo,headers); assertEquals(0, impl.getApparentAgeSecs(entry)); } @Test public void testCorrectedReceivedAgeIsAgeHeaderIfLarger() { final Header[] headers = new Header[] { new BasicHeader("Age", "10"), }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); impl = new CacheValidityPolicy() { @Override protected long getApparentAgeSecs(final HttpCacheEntry entry) { return 6; } }; assertEquals(10, impl.getCorrectedReceivedAgeSecs(entry)); } @Test public void testCorrectedReceivedAgeIsApparentAgeIfLarger() { final Header[] headers = new Header[] { new BasicHeader("Age", "6"), }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); impl = new CacheValidityPolicy() { @Override protected long getApparentAgeSecs(final HttpCacheEntry entry) { return 10; } }; assertEquals(10, impl.getCorrectedReceivedAgeSecs(entry)); } @Test public void testResponseDelayIsDifferenceBetweenResponseAndRequestTimes() { final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, sixSecondsAgo); assertEquals(4, impl.getResponseDelaySecs(entry)); } @Test public void testCorrectedInitialAgeIsCorrectedReceivedAgePlusResponseDelay() { final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); impl = new CacheValidityPolicy() { @Override protected long getCorrectedReceivedAgeSecs(final HttpCacheEntry entry) { return 7; } @Override protected long getResponseDelaySecs(final HttpCacheEntry entry) { return 13; } }; assertEquals(20, impl.getCorrectedInitialAgeSecs(entry)); } @Test public void testResidentTimeSecondsIsTimeSinceResponseTime() { final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, sixSecondsAgo); impl = new CacheValidityPolicy(); assertEquals(6, impl.getResidentTimeSecs(entry, now)); } @Test public void testCurrentAgeIsCorrectedInitialAgePlusResidentTime() { final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); impl = new CacheValidityPolicy() { @Override protected long getCorrectedInitialAgeSecs(final HttpCacheEntry entry) { return 11; } @Override protected long getResidentTimeSecs(final HttpCacheEntry entry, final Date d) { return 17; } }; assertEquals(28, impl.getCurrentAgeSecs(entry, new Date())); } @Test public void testFreshnessLifetimeIsSMaxAgeIfPresent() { final Header[] headers = new Header[] { new BasicHeader("Cache-Control", "s-maxage=10") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertEquals(10, impl.getFreshnessLifetimeSecs(entry)); } @Test public void testFreshnessLifetimeIsMaxAgeIfPresent() { final Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertEquals(10, impl.getFreshnessLifetimeSecs(entry)); } @Test public void testFreshnessLifetimeIsMostRestrictiveOfMaxAgeAndSMaxAge() { Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10"), new BasicHeader("Cache-Control", "s-maxage=20") }; HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertEquals(10, impl.getFreshnessLifetimeSecs(entry)); headers = new Header[] { new BasicHeader("Cache-Control", "max-age=20"), new BasicHeader("Cache-Control", "s-maxage=10") }; entry = HttpTestUtils.makeCacheEntry(headers); assertEquals(10, impl.getFreshnessLifetimeSecs(entry)); } @Test public void testFreshnessLifetimeIsMaxAgeEvenIfExpiresIsPresent() { final Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10"), new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertEquals(10, impl.getFreshnessLifetimeSecs(entry)); } @Test public void testFreshnessLifetimeIsSMaxAgeEvenIfExpiresIsPresent() { final Header[] headers = new Header[] { new BasicHeader("Cache-Control", "s-maxage=10"), new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertEquals(10, impl.getFreshnessLifetimeSecs(entry)); } @Test public void testFreshnessLifetimeIsFromExpiresHeaderIfNoMaxAge() { final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertEquals(4, impl.getFreshnessLifetimeSecs(entry)); } @Test public void testHeuristicFreshnessLifetime() { final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(oneSecondAgo)), new BasicHeader("Last-Modified", DateUtils.formatDate(elevenSecondsAgo)) }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertEquals(1, impl.getHeuristicFreshnessLifetimeSecs(entry, 0.1f, 0)); } @Test public void testHeuristicFreshnessLifetimeDefaultsProperly() { final long defaultFreshness = 10; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); assertEquals(defaultFreshness, impl.getHeuristicFreshnessLifetimeSecs(entry, 0.1f, defaultFreshness)); } @Test public void testHeuristicFreshnessLifetimeIsNonNegative() { final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(elevenSecondsAgo)), new BasicHeader("Last-Modified", DateUtils.formatDate(oneSecondAgo)) }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertTrue(impl.getHeuristicFreshnessLifetimeSecs(entry, 0.1f, 10) >= 0); } @Test public void testResponseIsFreshIfFreshnessLifetimeExceedsCurrentAge() { final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); impl = new CacheValidityPolicy() { @Override public long getCurrentAgeSecs(final HttpCacheEntry e, final Date d) { assertSame(entry, e); assertEquals(now, d); return 6; } @Override public long getFreshnessLifetimeSecs(final HttpCacheEntry e) { assertSame(entry, e); return 10; } }; assertTrue(impl.isResponseFresh(entry, now)); } @Test public void testResponseIsNotFreshIfFreshnessLifetimeEqualsCurrentAge() { final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); impl = new CacheValidityPolicy() { @Override public long getCurrentAgeSecs(final HttpCacheEntry e, final Date d) { assertEquals(now, d); assertSame(entry, e); return 6; } @Override public long getFreshnessLifetimeSecs(final HttpCacheEntry e) { assertSame(entry, e); return 6; } }; assertFalse(impl.isResponseFresh(entry, now)); } @Test public void testResponseIsNotFreshIfCurrentAgeExceedsFreshnessLifetime() { final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); impl = new CacheValidityPolicy() { @Override public long getCurrentAgeSecs(final HttpCacheEntry e, final Date d) { assertEquals(now, d); assertSame(entry, e); return 10; } @Override public long getFreshnessLifetimeSecs(final HttpCacheEntry e) { assertSame(entry, e); return 6; } }; assertFalse(impl.isResponseFresh(entry, now)); } @Test public void testCacheEntryIsRevalidatableIfHeadersIncludeETag() { final Header[] headers = { new BasicHeader("Expires", DateUtils.formatDate(new Date())), new BasicHeader("ETag", "somevalue")}; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertTrue(impl.isRevalidatable(entry)); } @Test public void testCacheEntryIsRevalidatableIfHeadersIncludeLastModifiedDate() { final Header[] headers = { new BasicHeader("Expires", DateUtils.formatDate(new Date())), new BasicHeader("Last-Modified", DateUtils.formatDate(new Date())) }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertTrue(impl.isRevalidatable(entry)); } @Test public void testCacheEntryIsNotRevalidatableIfNoAppropriateHeaders() { final Header[] headers = { new BasicHeader("Expires", DateUtils.formatDate(new Date())), new BasicHeader("Cache-Control", "public") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertFalse(impl.isRevalidatable(entry)); } @Test public void testMissingContentLengthDoesntInvalidateEntry() { final int contentLength = 128; final Header[] headers = {}; // no Content-Length header final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers, HttpTestUtils.getRandomBytes(contentLength)); assertTrue(impl.contentLengthHeaderMatchesActualLength(entry)); } @Test public void testCorrectContentLengthDoesntInvalidateEntry() { final int contentLength = 128; final Header[] headers = { new BasicHeader(HTTP.CONTENT_LEN, Integer.toString(contentLength)) }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers, HttpTestUtils.getRandomBytes(contentLength)); assertTrue(impl.contentLengthHeaderMatchesActualLength(entry)); } @Test public void testWrongContentLengthInvalidatesEntry() { final int contentLength = 128; final Header[] headers = {new BasicHeader(HTTP.CONTENT_LEN, Integer.toString(contentLength+1))}; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers, HttpTestUtils.getRandomBytes(contentLength)); assertFalse(impl.contentLengthHeaderMatchesActualLength(entry)); } @Test public void testMalformedContentLengthReturnsNegativeOne() { final Header[] headers = new Header[] { new BasicHeader("Content-Length", "asdf") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertEquals(-1, impl.getContentLengthValue(entry)); } @Test public void testNegativeAgeHeaderValueReturnsMaxAge() { final Header[] headers = new Header[] { new BasicHeader("Age", "-100") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertEquals(CacheValidityPolicy.MAX_AGE, impl.getAgeValue(entry)); } @Test public void testMalformedAgeHeaderValueReturnsMaxAge() { final Header[] headers = new Header[] { new BasicHeader("Age", "asdf") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertEquals(CacheValidityPolicy.MAX_AGE, impl.getAgeValue(entry)); } @Test public void testMalformedCacheControlMaxAgeHeaderReturnsZero() { final Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=asdf") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertEquals(0, impl.getMaxAge(entry)); } @Test public void testMalformedExpirationDateReturnsNull() { final Header[] headers = new Header[] { new BasicHeader("Expires", "asdf") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertNull(impl.getExpirationDate(entry)); } @Test public void testMustRevalidateIsFalseIfDirectiveNotPresent() { final Header[] headers = new Header[] { new BasicHeader("Cache-Control","public") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertFalse(impl.mustRevalidate(entry)); } @Test public void testMustRevalidateIsTrueWhenDirectiveIsPresent() { final Header[] headers = new Header[] { new BasicHeader("Cache-Control","public, must-revalidate") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertTrue(impl.mustRevalidate(entry)); } @Test public void testProxyRevalidateIsFalseIfDirectiveNotPresent() { final Header[] headers = new Header[] { new BasicHeader("Cache-Control","public") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertFalse(impl.proxyRevalidate(entry)); } @Test public void testProxyRevalidateIsTrueWhenDirectiveIsPresent() { final Header[] headers = new Header[] { new BasicHeader("Cache-Control","public, proxy-revalidate") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); assertTrue(impl.proxyRevalidate(entry)); } @Test public void testMayReturnStaleIfErrorInResponseIsTrueWithinStaleness(){ final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=5, stale-if-error=15") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpRequest req = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); assertTrue(impl.mayReturnStaleIfError(req, entry, now)); } @Test public void testMayReturnStaleIfErrorInRequestIsTrueWithinStaleness(){ final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=5") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpRequest req = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); req.setHeader("Cache-Control","stale-if-error=15"); assertTrue(impl.mayReturnStaleIfError(req, entry, now)); } @Test public void testMayNotReturnStaleIfErrorInResponseAndAfterResponseWindow(){ final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=5, stale-if-error=1") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpRequest req = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); assertFalse(impl.mayReturnStaleIfError(req, entry, now)); } @Test public void testMayNotReturnStaleIfErrorInResponseAndAfterRequestWindow(){ final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=5") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpRequest req = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); req.setHeader("Cache-Control","stale-if-error=1"); assertFalse(impl.mayReturnStaleIfError(req, entry, now)); } @Test public void testMayReturnStaleWhileRevalidatingIsFalseWhenDirectiveIsAbsent() { final Date now = new Date(); final Header[] headers = new Header[] { new BasicHeader("Cache-control", "public") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); final CacheValidityPolicy impl = new CacheValidityPolicy(); assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now)); } @Test public void testMayReturnStaleWhileRevalidatingIsTrueWhenWithinStaleness() { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=5, stale-while-revalidate=15") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final CacheValidityPolicy impl = new CacheValidityPolicy(); assertTrue(impl.mayReturnStaleWhileRevalidating(entry, now)); } @Test public void testMayReturnStaleWhileRevalidatingIsFalseWhenPastStaleness() { final Date now = new Date(); final Date twentyFiveSecondsAgo = new Date(now.getTime() - 25 * 1000L); final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(twentyFiveSecondsAgo)), new BasicHeader("Cache-Control", "max-age=5, stale-while-revalidate=15") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final CacheValidityPolicy impl = new CacheValidityPolicy(); assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now)); } @Test public void testMayReturnStaleWhileRevalidatingIsFalseWhenDirectiveEmpty() { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Cache-Control", "max-age=5, stale-while-revalidate=") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final CacheValidityPolicy impl = new CacheValidityPolicy(); assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now)); } } ././@LongLink0100644 0000000 0000000 00000000162 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExec.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCac0100644 0000000 0000000 00000040557 12301751714 032255 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.isA; import static org.easymock.EasyMock.isNull; import static org.easymock.EasyMock.same; import static org.easymock.classextension.EasyMock.createMockBuilder; import static org.easymock.classextension.EasyMock.createNiceMock; import static org.easymock.classextension.EasyMock.replay; import static org.easymock.classextension.EasyMock.verify; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.DateUtils; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.execchain.ClientExecChain; import org.apache.http.message.BasicHttpRequest; import org.apache.http.message.BasicHttpResponse; import org.apache.http.message.BasicStatusLine; import org.apache.http.protocol.HTTP; import org.easymock.IExpectationSetters; import org.easymock.classextension.EasyMock; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestCachingExec extends TestCachingExecChain { private static final String GET_CURRENT_DATE = "getCurrentDate"; private static final String HANDLE_BACKEND_RESPONSE = "handleBackendResponse"; private static final String CALL_BACKEND = "callBackend"; private static final String REVALIDATE_CACHE_ENTRY = "revalidateCacheEntry"; private CachingExec impl; private boolean mockedImpl; private CloseableHttpResponse mockBackendResponse; private Date requestDate; private Date responseDate; @Override @Before public void setUp() { super.setUp(); mockBackendResponse = createNiceMock(CloseableHttpResponse.class); requestDate = new Date(System.currentTimeMillis() - 1000); responseDate = new Date(); } @Override public CachingExec createCachingExecChain(final ClientExecChain mockBackend, final HttpCache mockCache, final CacheValidityPolicy mockValidityPolicy, final ResponseCachingPolicy mockResponsePolicy, final CachedHttpResponseGenerator mockResponseGenerator, final CacheableRequestPolicy mockRequestPolicy, final CachedResponseSuitabilityChecker mockSuitabilityChecker, final ConditionalRequestBuilder mockConditionalRequestBuilder, final ResponseProtocolCompliance mockResponseProtocolCompliance, final RequestProtocolCompliance mockRequestProtocolCompliance, final CacheConfig config, final AsynchronousValidator asyncValidator) { return impl = new CachingExec( mockBackend, mockCache, mockValidityPolicy, mockResponsePolicy, mockResponseGenerator, mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder, mockResponseProtocolCompliance, mockRequestProtocolCompliance, config, asyncValidator); } @Override public CachingExec createCachingExecChain(final ClientExecChain backend, final HttpCache cache, final CacheConfig config) { return impl = new CachingExec(backend, cache, config); } @Override protected void replayMocks() { super.replayMocks(); replay(mockBackendResponse); if (mockedImpl) { replay(impl); } } @Override protected void verifyMocks() { super.verifyMocks(); verify(mockBackendResponse); if (mockedImpl) { verify(impl); } } @Test public void testRequestThatCannotBeServedFromCacheCausesBackendRequest() throws Exception { cacheInvalidatorWasCalled(); requestPolicyAllowsCaching(false); mockImplMethods(CALL_BACKEND); implExpectsAnyRequestAndReturn(mockBackendResponse); requestIsFatallyNonCompliant(null); replayMocks(); final HttpResponse result = impl.execute(route, request, context); verifyMocks(); Assert.assertSame(mockBackendResponse, result); } @Test public void testCacheMissCausesBackendRequest() throws Exception { mockImplMethods(CALL_BACKEND); cacheInvalidatorWasCalled(); requestPolicyAllowsCaching(true); getCacheEntryReturns(null); getVariantCacheEntriesReturns(new HashMap()); requestIsFatallyNonCompliant(null); implExpectsAnyRequestAndReturn(mockBackendResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context); verifyMocks(); Assert.assertSame(mockBackendResponse, result); Assert.assertEquals(1, impl.getCacheMisses()); Assert.assertEquals(0, impl.getCacheHits()); Assert.assertEquals(0, impl.getCacheUpdates()); } @Test public void testUnsuitableUnvalidatableCacheEntryCausesBackendRequest() throws Exception { mockImplMethods(CALL_BACKEND); cacheInvalidatorWasCalled(); requestPolicyAllowsCaching(true); requestIsFatallyNonCompliant(null); getCacheEntryReturns(mockCacheEntry); cacheEntrySuitable(false); cacheEntryValidatable(false); expect(mockConditionalRequestBuilder.buildConditionalRequest(request, mockCacheEntry)) .andReturn(request); backendExpectsRequestAndReturn(request, mockBackendResponse); expect(mockBackendResponse.getProtocolVersion()).andReturn(HttpVersion.HTTP_1_1); expect(mockBackendResponse.getStatusLine()).andReturn( new BasicStatusLine(HttpVersion.HTTP_1_1, 200, "Ok")); replayMocks(); final HttpResponse result = impl.execute(route, request, context); verifyMocks(); Assert.assertSame(mockBackendResponse, result); Assert.assertEquals(0, impl.getCacheMisses()); Assert.assertEquals(1, impl.getCacheHits()); Assert.assertEquals(1, impl.getCacheUpdates()); } @Test public void testUnsuitableValidatableCacheEntryCausesRevalidation() throws Exception { mockImplMethods(REVALIDATE_CACHE_ENTRY); cacheInvalidatorWasCalled(); requestPolicyAllowsCaching(true); requestIsFatallyNonCompliant(null); getCacheEntryReturns(mockCacheEntry); cacheEntrySuitable(false); cacheEntryValidatable(true); cacheEntryMustRevalidate(false); cacheEntryProxyRevalidate(false); mayReturnStaleWhileRevalidating(false); expect(impl.revalidateCacheEntry( isA(HttpRoute.class), isA(HttpRequestWrapper.class), isA(HttpClientContext.class), (HttpExecutionAware) isNull(), isA(HttpCacheEntry.class))).andReturn(mockBackendResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context); verifyMocks(); Assert.assertSame(mockBackendResponse, result); Assert.assertEquals(0, impl.getCacheMisses()); Assert.assertEquals(1, impl.getCacheHits()); Assert.assertEquals(0, impl.getCacheUpdates()); } @Test public void testRevalidationCallsHandleBackEndResponseWhenNot200Or304() throws Exception { mockImplMethods(GET_CURRENT_DATE, HANDLE_BACKEND_RESPONSE); final HttpRequestWrapper validate = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final CloseableHttpResponse originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_FOUND, "Not Found")); final CloseableHttpResponse finalResponse = Proxies.enhanceResponse( HttpTestUtils.make200Response()); conditionalRequestBuilderReturns(validate); getCurrentDateReturns(requestDate); backendExpectsRequestAndReturn(validate, originResponse); getCurrentDateReturns(responseDate); expect(impl.handleBackendResponse( eq(route), same(validate), same(context), (HttpExecutionAware) isNull(), eq(requestDate), eq(responseDate), same(originResponse))).andReturn(finalResponse); replayMocks(); final HttpResponse result = impl.revalidateCacheEntry(route, request, context, null, entry); verifyMocks(); Assert.assertSame(finalResponse, result); } @Test public void testRevalidationUpdatesCacheEntryAndPutsItToCacheWhen304ReturningCachedResponse() throws Exception { mockImplMethods(GET_CURRENT_DATE); final HttpRequestWrapper validate = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified")); final HttpCacheEntry updatedEntry = HttpTestUtils.makeCacheEntry(); conditionalRequestBuilderReturns(validate); getCurrentDateReturns(requestDate); backendExpectsRequestAndReturn(validate, originResponse); getCurrentDateReturns(responseDate); expect(mockCache.updateCacheEntry( eq(host), same(request), same(entry), same(originResponse), eq(requestDate), eq(responseDate))) .andReturn(updatedEntry); expect(mockSuitabilityChecker.isConditional(request)).andReturn(false); responseIsGeneratedFromCache(); replayMocks(); impl.revalidateCacheEntry(route, request, context, null, entry); verifyMocks(); } @Test public void testEndlessResponsesArePassedThrough() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setHeader("Date", DateUtils.formatDate(new Date())); resp1.setHeader("Server", "MockOrigin/1.0"); resp1.setHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING); final AtomicInteger size = new AtomicInteger(); final AtomicInteger maxlength = new AtomicInteger(Integer.MAX_VALUE); resp1.setEntity(new InputStreamEntity(new InputStream() { private Throwable closed; @Override public void close() throws IOException { closed = new Throwable(); super.close(); } @Override public int read() throws IOException { Thread.yield(); if (closed != null) { throw new IOException("Response has been closed"); } if (size.incrementAndGet() > maxlength.get()) { return -1; } return 'y'; } }, -1)); final CloseableHttpResponse resp = mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull()); EasyMock.expect(resp).andReturn(Proxies.enhanceResponse(resp1)); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); replayMocks(); final CloseableHttpResponse resp2 = impl.execute(route, req1, context, null); maxlength.set(size.get() * 2); verifyMocks(); assertTrue(HttpTestUtils.semanticallyTransparent(resp1, resp2)); } @Test public void testCallBackendMakesBackEndRequestAndHandlesResponse() throws Exception { mockImplMethods(GET_CURRENT_DATE, HANDLE_BACKEND_RESPONSE); final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); getCurrentDateReturns(requestDate); backendExpectsRequestAndReturn(request, resp); getCurrentDateReturns(responseDate); handleBackendResponseReturnsResponse(request, resp); replayMocks(); impl.callBackend(route, request, context, null); verifyMocks(); } private IExpectationSetters implExpectsAnyRequestAndReturn( final CloseableHttpResponse response) throws Exception { final CloseableHttpResponse resp = impl.callBackend( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull()); return EasyMock.expect(resp).andReturn(response); } private void getVariantCacheEntriesReturns(final Map result) throws IOException { expect(mockCache.getVariantCacheEntriesWithEtags(host, request)).andReturn(result); } private void cacheInvalidatorWasCalled() throws IOException { mockCache.flushInvalidatedCacheEntriesFor( (HttpHost)anyObject(), (HttpRequest)anyObject()); } private void getCurrentDateReturns(final Date date) { expect(impl.getCurrentDate()).andReturn(date); } private void handleBackendResponseReturnsResponse(final HttpRequestWrapper request, final HttpResponse response) throws IOException { expect( impl.handleBackendResponse( isA(HttpRoute.class), same(request), isA(HttpClientContext.class), (HttpExecutionAware) isNull(), isA(Date.class), isA(Date.class), isA(CloseableHttpResponse.class))).andReturn( Proxies.enhanceResponse(response)); } private void mockImplMethods(final String... methods) { mockedImpl = true; impl = createMockBuilder(CachingExec.class).withConstructor( mockBackend, mockCache, mockValidityPolicy, mockResponsePolicy, mockResponseGenerator, mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder, mockResponseProtocolCompliance, mockRequestProtocolCompliance, config, asyncValidator).addMockedMethods(methods).createNiceMock(); } } ././@LongLink0100644 0000000 0000000 00000000167 12302131606 011631 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExecChain.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCac0100644 0000000 0000000 00000234460 12301751715 032254 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.isA; import static org.easymock.EasyMock.isNull; import static org.easymock.classextension.EasyMock.createNiceMock; import static org.easymock.classextension.EasyMock.replay; import static org.easymock.classextension.EasyMock.verify; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.InputStream; import java.net.SocketException; import java.net.SocketTimeoutException; import java.util.ArrayList; import java.util.Date; import java.util.List; import junit.framework.AssertionFailedError; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ResponseHandler; import org.apache.http.client.cache.CacheResponseStatus; import org.apache.http.client.cache.HttpCacheContext; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpOptions; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.DateUtils; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.execchain.ClientExecChain; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpRequest; import org.apache.http.message.BasicHttpResponse; import org.apache.http.util.EntityUtils; import org.easymock.Capture; import org.easymock.IExpectationSetters; import org.easymock.classextension.EasyMock; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public abstract class TestCachingExecChain { private ClientExecChain impl; protected CacheValidityPolicy mockValidityPolicy; protected CacheableRequestPolicy mockRequestPolicy; protected ClientExecChain mockBackend; protected HttpCache mockCache; private HttpCacheStorage mockStorage; protected CachedResponseSuitabilityChecker mockSuitabilityChecker; protected ResponseCachingPolicy mockResponsePolicy; protected HttpCacheEntry mockCacheEntry; protected CachedHttpResponseGenerator mockResponseGenerator; private ResponseHandler mockHandler; private HttpUriRequest mockUriRequest; private CloseableHttpResponse mockCachedResponse; protected ConditionalRequestBuilder mockConditionalRequestBuilder; private HttpRequest mockConditionalRequest; private StatusLine mockStatusLine; protected ResponseProtocolCompliance mockResponseProtocolCompliance; protected RequestProtocolCompliance mockRequestProtocolCompliance; protected CacheConfig config; protected AsynchronousValidator asyncValidator; protected HttpRoute route; protected HttpHost host; protected HttpRequestWrapper request; protected HttpCacheContext context; protected HttpCacheEntry entry; @SuppressWarnings("unchecked") @Before public void setUp() { mockRequestPolicy = createNiceMock(CacheableRequestPolicy.class); mockValidityPolicy = createNiceMock(CacheValidityPolicy.class); mockBackend = createNiceMock(ClientExecChain.class); mockCache = createNiceMock(HttpCache.class); mockSuitabilityChecker = createNiceMock(CachedResponseSuitabilityChecker.class); mockResponsePolicy = createNiceMock(ResponseCachingPolicy.class); mockHandler = createNiceMock(ResponseHandler.class); mockUriRequest = createNiceMock(HttpUriRequest.class); mockCacheEntry = createNiceMock(HttpCacheEntry.class); mockResponseGenerator = createNiceMock(CachedHttpResponseGenerator.class); mockCachedResponse = createNiceMock(CloseableHttpResponse.class); mockConditionalRequestBuilder = createNiceMock(ConditionalRequestBuilder.class); mockConditionalRequest = createNiceMock(HttpRequest.class); mockStatusLine = createNiceMock(StatusLine.class); mockResponseProtocolCompliance = createNiceMock(ResponseProtocolCompliance.class); mockRequestProtocolCompliance = createNiceMock(RequestProtocolCompliance.class); mockStorage = createNiceMock(HttpCacheStorage.class); config = CacheConfig.DEFAULT; asyncValidator = new AsynchronousValidator(config); host = new HttpHost("foo.example.com"); route = new HttpRoute(host); request = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/stuff", HttpVersion.HTTP_1_1)); context = HttpCacheContext.create(); context.setTargetHost(host); entry = HttpTestUtils.makeCacheEntry(); impl = createCachingExecChain(mockBackend, mockCache, mockValidityPolicy, mockResponsePolicy, mockResponseGenerator, mockRequestPolicy, mockSuitabilityChecker, mockConditionalRequestBuilder, mockResponseProtocolCompliance, mockRequestProtocolCompliance, config, asyncValidator); } public abstract ClientExecChain createCachingExecChain(ClientExecChain backend, HttpCache responseCache, CacheValidityPolicy validityPolicy, ResponseCachingPolicy responseCachingPolicy, CachedHttpResponseGenerator responseGenerator, CacheableRequestPolicy cacheableRequestPolicy, CachedResponseSuitabilityChecker suitabilityChecker, ConditionalRequestBuilder conditionalRequestBuilder, ResponseProtocolCompliance responseCompliance, RequestProtocolCompliance requestCompliance, CacheConfig config, AsynchronousValidator asynchRevalidator); public abstract ClientExecChain createCachingExecChain(ClientExecChain backend, HttpCache cache, CacheConfig config); public static HttpRequestWrapper eqRequest(final HttpRequestWrapper in) { EasyMock.reportMatcher(new RequestEquivalent(in)); return null; } public static R eqResponse(final R in) { EasyMock.reportMatcher(new ResponseEquivalent(in)); return null; } protected void replayMocks() { replay(mockRequestPolicy); replay(mockValidityPolicy); replay(mockSuitabilityChecker); replay(mockResponsePolicy); replay(mockCacheEntry); replay(mockResponseGenerator); replay(mockBackend); replay(mockCache); replay(mockHandler); replay(mockUriRequest); replay(mockCachedResponse); replay(mockConditionalRequestBuilder); replay(mockConditionalRequest); replay(mockStatusLine); replay(mockResponseProtocolCompliance); replay(mockRequestProtocolCompliance); replay(mockStorage); } protected void verifyMocks() { verify(mockRequestPolicy); verify(mockValidityPolicy); verify(mockSuitabilityChecker); verify(mockResponsePolicy); verify(mockCacheEntry); verify(mockResponseGenerator); verify(mockBackend); verify(mockCache); verify(mockHandler); verify(mockUriRequest); verify(mockCachedResponse); verify(mockConditionalRequestBuilder); verify(mockConditionalRequest); verify(mockStatusLine); verify(mockResponseProtocolCompliance); verify(mockRequestProtocolCompliance); verify(mockStorage); } @Test public void testCacheableResponsesGoIntoCache() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control", "max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); } @Test public void testOlderCacheableResponsesDoNotGoIntoCache() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final Date now = new Date(); final Date fiveSecondsAgo = new Date(now.getTime() - 5 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("Etag", "\"new-etag\""); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("Cache-Control", "no-cache"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag", "\"old-etag\""); resp2.setHeader("Date", DateUtils.formatDate(fiveSecondsAgo)); resp2.setHeader("Cache-Control", "max-age=3600"); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); final HttpResponse result = impl.execute(route, req3, context, null); verifyMocks(); assertEquals("\"new-etag\"", result.getFirstHeader("ETag").getValue()); } @Test public void testNewerCacheableResponsesReplaceExistingCacheEntry() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final Date now = new Date(); final Date fiveSecondsAgo = new Date(now.getTime() - 5 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(fiveSecondsAgo)); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("Etag", "\"old-etag\""); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("Cache-Control", "max-age=0"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag", "\"new-etag\""); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader("Cache-Control", "max-age=3600"); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); final HttpResponse result = impl.execute(route, req3, context, null); verifyMocks(); assertEquals("\"new-etag\"", result.getFirstHeader("ETag").getValue()); } protected void requestIsFatallyNonCompliant(final RequestProtocolError error) { final List errors = new ArrayList(); if (error != null) { errors.add(error); } expect(mockRequestProtocolCompliance.requestIsFatallyNonCompliant(eqRequest(request))) .andReturn(errors); } @Test public void testSuitableCacheEntryDoesNotCauseBackendRequest() throws Exception { cacheInvalidatorWasCalled(); requestPolicyAllowsCaching(true); getCacheEntryReturns(mockCacheEntry); cacheEntrySuitable(true); responseIsGeneratedFromCache(); requestIsFatallyNonCompliant(null); entryHasStaleness(0L); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertSame(mockCachedResponse, result); } @Test public void testNonCacheableResponseIsNotCachedAndIsReturnedAsIs() throws Exception { final CacheConfig config = CacheConfig.DEFAULT; impl = createCachingExecChain(mockBackend, new BasicHttpCache(new HeapResourceFactory(), mockStorage, config), config); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control", "no-cache"); expect(mockStorage.getEntry(isA(String.class))).andReturn(null).anyTimes(); mockStorage.removeEntry(isA(String.class)); expectLastCall().anyTimes(); backendExpectsAnyRequestAndReturn(resp1); replayMocks(); final HttpResponse result = impl.execute(route, req1, context, null); verifyMocks(); assertTrue(HttpTestUtils.semanticallyTransparent(resp1, result)); } @Test public void testResponseIsGeneratedWhenCacheEntryIsUsable() throws Exception { requestIsFatallyNonCompliant(null); cacheInvalidatorWasCalled(); requestPolicyAllowsCaching(true); cacheEntrySuitable(true); getCacheEntryReturns(mockCacheEntry); responseIsGeneratedFromCache(); entryHasStaleness(0L); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); } @Test public void testNonCompliantRequestWrapsAndReThrowsProtocolException() throws Exception { final ClientProtocolException expected = new ClientProtocolException("ouch"); requestIsFatallyNonCompliant(null); mockRequestProtocolCompliance.makeRequestCompliant((HttpRequestWrapper) anyObject()); expectLastCall().andThrow(expected); boolean gotException = false; replayMocks(); try { impl.execute(route, request, context, null); } catch (final ClientProtocolException ex) { Assert.assertSame(expected, ex); gotException = true; } verifyMocks(); Assert.assertTrue(gotException); } @Test public void testSetsModuleGeneratedResponseContextForCacheOptionsResponse() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req = HttpRequestWrapper.wrap(new BasicHttpRequest("OPTIONS", "*", HttpVersion.HTTP_1_1)); req.setHeader("Max-Forwards", "0"); impl.execute(route, req, context, null); Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE, context.getCacheResponseStatus()); } @Test public void testSetsModuleGeneratedResponseContextForFatallyNoncompliantRequest() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req.setHeader("Range", "bytes=0-50"); req.setHeader("If-Range", "W/\"weak-etag\""); impl.execute(route, req, context, null); Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE, context.getCacheResponseStatus()); } @Test public void testRecordsClientProtocolInViaHeaderIfRequestNotServableFromCache() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_0)); req.setHeader("Cache-Control", "no-cache"); final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, "No Content"); final Capture cap = new Capture(); backendCaptureRequestAndReturn(cap, resp); replayMocks(); impl.execute(route, req, context, null); verifyMocks(); final HttpRequest captured = cap.getValue(); final String via = captured.getFirstHeader("Via").getValue(); final String proto = via.split("\\s+")[0]; Assert.assertTrue("http/1.0".equalsIgnoreCase(proto) || "1.0".equalsIgnoreCase(proto)); } @Test public void testSetsCacheMissContextIfRequestNotServableFromCache() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req.setHeader("Cache-Control", "no-cache"); final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, "No Content"); backendExpectsAnyRequestAndReturn(resp); replayMocks(); impl.execute(route, req, context, null); verifyMocks(); Assert.assertEquals(CacheResponseStatus.CACHE_MISS, context.getCacheResponseStatus()); } @Test public void testSetsViaHeaderOnResponseIfRequestNotServableFromCache() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req.setHeader("Cache-Control", "no-cache"); final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, "No Content"); backendExpectsAnyRequestAndReturn(resp); replayMocks(); final HttpResponse result = impl.execute(route, req, context, null); verifyMocks(); Assert.assertNotNull(result.getFirstHeader("Via")); } @Test public void testSetsViaHeaderOnResponseForCacheMiss() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(new Date())); resp1.setHeader("Cache-Control", "public, max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); replayMocks(); final HttpResponse result = impl.execute(route, req1, context, null); verifyMocks(); Assert.assertNotNull(result.getFirstHeader("Via")); } @Test public void testSetsCacheHitContextIfRequestServedFromCache() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(new Date())); resp1.setHeader("Cache-Control", "public, max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(CacheResponseStatus.CACHE_HIT, context.getCacheResponseStatus()); } @Test public void testSetsViaHeaderOnResponseIfRequestServedFromCache() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(new Date())); resp1.setHeader("Cache-Control", "public, max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertNotNull(result.getFirstHeader("Via")); } @Test public void testReturns304ForIfModifiedSinceHeaderIfRequestServedFromCache() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req2.addHeader("If-Modified-Since", DateUtils.formatDate(now)); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "public, max-age=3600"); resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode()); } @Test public void testReturns304ForIfModifiedSinceHeaderIf304ResponseInCache() throws Exception { final Date now = new Date(); final Date oneHourAgo = new Date(now.getTime() - 3600 * 1000L); final Date inTenMinutes = new Date(now.getTime() + 600 * 1000L); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req1.addHeader("If-Modified-Since", DateUtils.formatDate(oneHourAgo)); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req2.addHeader("If-Modified-Since", DateUtils.formatDate(oneHourAgo)); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not modified"); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Cache-control", "max-age=600"); resp1.setHeader("Expires", DateUtils.formatDate(inTenMinutes)); expect( mockBackend.execute(eq(route), isA(HttpRequestWrapper.class), isA(HttpClientContext.class), (HttpExecutionAware) isNull())).andReturn( Proxies.enhanceResponse(resp1)).once(); expect( mockBackend.execute(eq(route), isA(HttpRequestWrapper.class), isA(HttpClientContext.class), (HttpExecutionAware) isNull())).andThrow( new AssertionFailedError("Should have reused cached 304 response")).anyTimes(); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode()); Assert.assertFalse(result.containsHeader("Last-Modified")); } @Test public void testReturns200ForIfModifiedSinceDateIsLess() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(new Date())); resp1.setHeader("Cache-Control", "public, max-age=3600"); resp1.setHeader("Last-Modified", DateUtils.formatDate(new Date())); // The variant has been modified since this date req2.addHeader("If-Modified-Since", DateUtils.formatDate(tenSecondsAgo)); final HttpResponse resp2 = HttpTestUtils.make200Response(); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode()); } @Test public void testReturns200ForIfModifiedSinceDateIsInvalid() throws Exception { final Date now = new Date(); final Date tenSecondsAfter = new Date(now.getTime() + 10 * 1000L); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(new Date())); resp1.setHeader("Cache-Control", "public, max-age=3600"); resp1.setHeader("Last-Modified", DateUtils.formatDate(new Date())); // invalid date (date in the future) req2.addHeader("If-Modified-Since", DateUtils.formatDate(tenSecondsAfter)); backendExpectsAnyRequestAndReturn(resp1).times(2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode()); } @Test public void testReturns304ForIfNoneMatchHeaderIfRequestServedFromCache() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req2.addHeader("If-None-Match", "*"); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(new Date())); resp1.setHeader("Cache-Control", "public, max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode()); } @Test public void testReturns200ForIfNoneMatchHeaderFails() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(new Date())); resp1.setHeader("Cache-Control", "public, max-age=3600"); req2.addHeader("If-None-Match", "\"abc\""); final HttpResponse resp2 = HttpTestUtils.make200Response(); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(200, result.getStatusLine().getStatusCode()); } @Test public void testReturns304ForIfNoneMatchHeaderAndIfModifiedSinceIfRequestServedFromCache() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "public, max-age=3600"); resp1.setHeader("Last-Modified", DateUtils.formatDate(new Date())); req2.addHeader("If-None-Match", "*"); req2.addHeader("If-Modified-Since", DateUtils.formatDate(now)); backendExpectsAnyRequestAndReturn(resp1); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode()); } @Test public void testReturns200ForIfNoneMatchHeaderFailsIfModifiedSinceIgnored() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req2.addHeader("If-None-Match", "\"abc\""); req2.addHeader("If-Modified-Since", DateUtils.formatDate(now)); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "public, max-age=3600"); resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp1); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(200, result.getStatusLine().getStatusCode()); } @Test public void testReturns200ForOptionsFollowedByGetIfAuthorizationHeaderAndSharedCache() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.custom() .setSharedCache(true).build()); final Date now = new Date(); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpOptions( "http://foo.example.com/")); req1.setHeader("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req2.setHeader("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, "No Content"); resp1.setHeader("Content-Length", "0"); resp1.setHeader("ETag", "\"options-etag\""); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Cache-Control", "public, max-age=3600"); resp1.setHeader("Last-Modified", DateUtils.formatDate(now)); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"get-etag\""); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Cache-Control", "public, max-age=3600"); resp1.setHeader("Last-Modified", DateUtils.formatDate(now)); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(200, result.getStatusLine().getStatusCode()); } @Test public void testSetsValidatedContextIfRequestWasSuccessfullyValidated() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "public, max-age=5"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp2.setEntity(HttpTestUtils.makeBody(128)); resp2.setHeader("Content-Length", "128"); resp2.setHeader("ETag", "\"etag\""); resp2.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp2.setHeader("Cache-Control", "public, max-age=5"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(CacheResponseStatus.VALIDATED, context.getCacheResponseStatus()); } @Test public void testSetsViaHeaderIfRequestWasSuccessfullyValidated() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "public, max-age=5"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp2.setEntity(HttpTestUtils.makeBody(128)); resp2.setHeader("Content-Length", "128"); resp2.setHeader("ETag", "\"etag\""); resp2.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp2.setHeader("Cache-Control", "public, max-age=5"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertNotNull(result.getFirstHeader("Via")); } @Test public void testSetsModuleResponseContextIfValidationRequiredButFailed() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "public, max-age=5, must-revalidate"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndThrows(new IOException()); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE, context.getCacheResponseStatus()); } @Test public void testSetsModuleResponseContextIfValidationFailsButNotRequired() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "public, max-age=5"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndThrows(new IOException()); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(CacheResponseStatus.CACHE_HIT, context.getCacheResponseStatus()); } @Test public void testSetViaHeaderIfValidationFailsButNotRequired() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "public, max-age=5"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndThrows(new IOException()); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertNotNull(result.getFirstHeader("Via")); } @Test public void testReturns304ForIfNoneMatchPassesIfRequestServedFromOrigin() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "public, max-age=5"); req2.addHeader("If-None-Match", "\"etag\""); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp2.setHeader("ETag", "\"etag\""); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader("Cache-Control", "public, max-age=5"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode()); } @Test public void testReturns200ForIfNoneMatchFailsIfRequestServedFromOrigin() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "public, max-age=5"); req2.addHeader("If-None-Match", "\"etag\""); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp2.setEntity(HttpTestUtils.makeBody(128)); resp2.setHeader("Content-Length", "128"); resp2.setHeader("ETag", "\"newetag\""); resp2.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp2.setHeader("Cache-Control", "public, max-age=5"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode()); } @Test public void testReturns304ForIfModifiedSincePassesIfRequestServedFromOrigin() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "public, max-age=5"); req2.addHeader("If-Modified-Since", DateUtils.formatDate(tenSecondsAgo)); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp2.setHeader("ETag", "\"etag\""); resp2.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo)); resp2.setHeader("Cache-Control", "public, max-age=5"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode()); } @Test public void testReturns200ForIfModifiedSinceFailsIfRequestServedFromOrigin() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "public, max-age=5"); req2.addHeader("If-Modified-Since", DateUtils.formatDate(tenSecondsAgo)); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp2.setEntity(HttpTestUtils.makeBody(128)); resp2.setHeader("Content-Length", "128"); resp2.setHeader("ETag", "\"newetag\""); resp2.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Last-Modified", DateUtils.formatDate(now)); resp2.setHeader("Cache-Control", "public, max-age=5"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode()); } @Test public void testVariantMissServerIfReturns304CacheReturns200() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final Date now = new Date(); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com")); req1.addHeader("Accept-Encoding", "gzip"); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("Etag", "\"gzip_etag\""); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Vary", "Accept-Encoding"); resp1.setHeader("Cache-Control", "public, max-age=3600"); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com")); req2.addHeader("Accept-Encoding", "deflate"); final HttpRequestWrapper req2Server = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com")); req2Server.addHeader("Accept-Encoding", "deflate"); req2Server.addHeader("If-None-Match", "\"gzip_etag\""); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp2.setEntity(HttpTestUtils.makeBody(128)); resp2.setHeader("Content-Length", "128"); resp2.setHeader("Etag", "\"deflate_etag\""); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader("Vary", "Accept-Encoding"); resp2.setHeader("Cache-Control", "public, max-age=3600"); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com")); req3.addHeader("Accept-Encoding", "gzip,deflate"); final HttpRequestWrapper req3Server = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com")); req3Server.addHeader("Accept-Encoding", "gzip,deflate"); req3Server.addHeader("If-None-Match", "\"gzip_etag\",\"deflate_etag\""); final HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Content-Length", "128"); resp3.setHeader("Etag", "\"gzip_etag\""); resp3.setHeader("Date", DateUtils.formatDate(now)); resp3.setHeader("Vary", "Accept-Encoding"); resp3.setHeader("Cache-Control", "public, max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); backendExpectsAnyRequestAndReturn(resp3); replayMocks(); final HttpResponse result1 = impl.execute(route, req1, context, null); final HttpResponse result2 = impl.execute(route, req2, context, null); final HttpResponse result3 = impl.execute(route, req3, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_OK, result1.getStatusLine().getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, result2.getStatusLine().getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, result3.getStatusLine().getStatusCode()); } @Test public void testVariantsMissServerReturns304CacheReturns304() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final Date now = new Date(); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com")); req1.addHeader("Accept-Encoding", "gzip"); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(HttpTestUtils.makeBody(128)); resp1.setHeader("Content-Length", "128"); resp1.setHeader("Etag", "\"gzip_etag\""); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Vary", "Accept-Encoding"); resp1.setHeader("Cache-Control", "public, max-age=3600"); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com")); req2.addHeader("Accept-Encoding", "deflate"); final HttpRequestWrapper req2Server = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com")); req2Server.addHeader("Accept-Encoding", "deflate"); req2Server.addHeader("If-None-Match", "\"gzip_etag\""); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp2.setEntity(HttpTestUtils.makeBody(128)); resp2.setHeader("Content-Length", "128"); resp2.setHeader("Etag", "\"deflate_etag\""); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader("Vary", "Accept-Encoding"); resp2.setHeader("Cache-Control", "public, max-age=3600"); final HttpRequestWrapper req4 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com")); req4.addHeader("Accept-Encoding", "gzip,identity"); req4.addHeader("If-None-Match", "\"gzip_etag\""); final HttpRequestWrapper req4Server = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com")); req4Server.addHeader("Accept-Encoding", "gzip,identity"); req4Server.addHeader("If-None-Match", "\"gzip_etag\""); final HttpResponse resp4 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp4.setHeader("Etag", "\"gzip_etag\""); resp4.setHeader("Date", DateUtils.formatDate(now)); resp4.setHeader("Vary", "Accept-Encoding"); resp4.setHeader("Cache-Control", "public, max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); backendExpectsAnyRequestAndReturn(resp4); replayMocks(); final HttpResponse result1 = impl.execute(route, req1, context, null); final HttpResponse result2 = impl.execute(route, req2, context, null); final HttpResponse result4 = impl.execute(route, req4, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_OK, result1.getStatusLine().getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, result2.getStatusLine().getStatusCode()); Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result4.getStatusLine().getStatusCode()); } @Test public void testSocketTimeoutExceptionIsNotSilentlyCatched() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final Date now = new Date(); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp1.setEntity(new InputStreamEntity(new InputStream() { private boolean closed = false; @Override public void close() throws IOException { closed = true; } @Override public int read() throws IOException { if (closed) { throw new SocketException("Socket closed"); } throw new SocketTimeoutException("Read timed out"); } }, 128)); resp1.setHeader("Date", DateUtils.formatDate(now)); backendExpectsAnyRequestAndReturn(resp1); replayMocks(); try { final HttpResponse result1 = impl.execute(route, req1, context, null); EntityUtils.toString(result1.getEntity()); Assert.fail("We should have had a SocketTimeoutException"); } catch (final SocketTimeoutException e) { } verifyMocks(); } @Test public void testIsSharedCache() { Assert.assertTrue(config.isSharedCache()); } @Test public void testTreatsCacheIOExceptionsAsCacheMiss() throws Exception { impl = createCachingExecChain(mockBackend, mockCache, CacheConfig.DEFAULT); final CloseableHttpResponse resp = Proxies.enhanceResponse(HttpTestUtils.make200Response()); mockCache.flushInvalidatedCacheEntriesFor(host, request); expectLastCall().andThrow(new IOException()).anyTimes(); mockCache.flushInvalidatedCacheEntriesFor(isA(HttpHost.class), isA(HttpRequest.class), isA(HttpResponse.class)); expectLastCall().anyTimes(); expect(mockCache.getCacheEntry(eq(host), isA(HttpRequest.class))).andThrow( new IOException()).anyTimes(); expect(mockCache.getVariantCacheEntriesWithEtags(eq(host), isA(HttpRequest.class))) .andThrow(new IOException()).anyTimes(); expect( mockCache.cacheAndReturnResponse(eq(host), isA(HttpRequest.class), isA(CloseableHttpResponse.class), isA(Date.class), isA(Date.class))) .andReturn(resp).anyTimes(); expect( mockBackend.execute(eq(route), isA(HttpRequestWrapper.class), isA(HttpClientContext.class), (HttpExecutionAware) isNull())).andReturn(resp); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertSame(resp, result); } @Test public void testIfOnlyIfCachedAndNoCacheEntryBackendNotCalled() throws Exception { impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); request.addHeader("Cache-Control", "only-if-cached"); final HttpResponse resp = impl.execute(route, request, context, null); Assert.assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT, resp.getStatusLine().getStatusCode()); } @Test public void testIfOnlyIfCachedAndEntryNotSuitableBackendNotCalled() throws Exception { request.setHeader("Cache-Control", "only-if-cached"); entry = HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("Cache-Control", "must-revalidate") }); requestIsFatallyNonCompliant(null); cacheInvalidatorWasCalled(); requestPolicyAllowsCaching(true); getCacheEntryReturns(entry); cacheEntrySuitable(false); replayMocks(); final HttpResponse resp = impl.execute(route, request, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT, resp.getStatusLine().getStatusCode()); } @Test public void testIfOnlyIfCachedAndEntryExistsAndIsSuitableReturnsEntry() throws Exception { request.setHeader("Cache-Control", "only-if-cached"); requestIsFatallyNonCompliant(null); cacheInvalidatorWasCalled(); requestPolicyAllowsCaching(true); getCacheEntryReturns(entry); cacheEntrySuitable(true); responseIsGeneratedFromCache(); entryHasStaleness(0); replayMocks(); final HttpResponse resp = impl.execute(route, request, context, null); verifyMocks(); Assert.assertSame(mockCachedResponse, resp); } @Test public void testDoesNotSetConnectionInContextOnCacheHit() throws Exception { final DummyBackend backend = new DummyBackend(); final HttpResponse response = HttpTestUtils.make200Response(); response.setHeader("Cache-Control", "max-age=3600"); backend.setResponse(response); impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpClientContext ctx = HttpClientContext.create(); ctx.setTargetHost(host); impl.execute(route, request, context, null); impl.execute(route, request, ctx, null); assertNull(ctx.getConnection()); } @Test public void testSetsTargetHostInContextOnCacheHit() throws Exception { final DummyBackend backend = new DummyBackend(); final HttpResponse response = HttpTestUtils.make200Response(); response.setHeader("Cache-Control", "max-age=3600"); backend.setResponse(response); impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpClientContext ctx = HttpClientContext.create(); ctx.setTargetHost(host); impl.execute(route, request, context, null); impl.execute(route, request, ctx, null); assertSame(host, ctx.getTargetHost()); } @Test public void testSetsRouteInContextOnCacheHit() throws Exception { final DummyBackend backend = new DummyBackend(); final HttpResponse response = HttpTestUtils.make200Response(); response.setHeader("Cache-Control", "max-age=3600"); backend.setResponse(response); impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpClientContext ctx = HttpClientContext.create(); ctx.setTargetHost(host); impl.execute(route, request, context, null); impl.execute(route, request, ctx, null); assertEquals(route, ctx.getHttpRoute()); } @Test public void testSetsRequestInContextOnCacheHit() throws Exception { final DummyBackend backend = new DummyBackend(); final HttpResponse response = HttpTestUtils.make200Response(); response.setHeader("Cache-Control", "max-age=3600"); backend.setResponse(response); impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpClientContext ctx = HttpClientContext.create(); ctx.setTargetHost(host); impl.execute(route, request, context, null); impl.execute(route, request, ctx, null); if (!HttpTestUtils.equivalent(request, ctx.getRequest())) { assertSame(request, ctx.getRequest()); } } @Test public void testSetsResponseInContextOnCacheHit() throws Exception { final DummyBackend backend = new DummyBackend(); final HttpResponse response = HttpTestUtils.make200Response(); response.setHeader("Cache-Control", "max-age=3600"); backend.setResponse(response); impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpClientContext ctx = HttpClientContext.create(); ctx.setTargetHost(host); impl.execute(route, request, context, null); final HttpResponse result = impl.execute(route, request, ctx, null); if (!HttpTestUtils.equivalent(result, ctx.getResponse())) { assertSame(result, ctx.getResponse()); } } @Test public void testSetsRequestSentInContextOnCacheHit() throws Exception { final DummyBackend backend = new DummyBackend(); final HttpResponse response = HttpTestUtils.make200Response(); response.setHeader("Cache-Control", "max-age=3600"); backend.setResponse(response); impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpClientContext ctx = HttpClientContext.create(); ctx.setTargetHost(host); impl.execute(route, request, context, null); impl.execute(route, request, ctx, null); assertTrue(ctx.isRequestSent()); } @Test public void testCanCacheAResponseWithoutABody() throws Exception { final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, "No Content"); response.setHeader("Date", DateUtils.formatDate(new Date())); response.setHeader("Cache-Control", "max-age=300"); final DummyBackend backend = new DummyBackend(); backend.setResponse(response); impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT); impl.execute(route, request, context, null); impl.execute(route, request, context, null); assertEquals(1, backend.getExecutions()); } @Test public void testNoEntityForIfNoneMatchRequestNotYetInCache() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req1.addHeader("If-None-Match", "\"etag\""); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not modified"); resp1.setHeader("Content-Length", "128"); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "public, max-age=5"); backendExpectsAnyRequestAndReturn(resp1); replayMocks(); final HttpResponse result = impl.execute(route, req1, context, null); verifyMocks(); assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode()); assertNull("The 304 response messages MUST NOT contain a message-body", result.getEntity()); } @Test public void testNotModifiedResponseUpdatesCacheEntryWhenNoEntity() throws Exception { final Date now = new Date(); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req1.addHeader("If-None-Match", "etag"); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req2.addHeader("If-None-Match", "etag"); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not modified"); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Cache-Control", "max-age=0"); resp1.setHeader("Etag", "etag"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not modified"); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader("Cache-Control", "max-age=0"); resp1.setHeader("Etag", "etag"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); final HttpResponse result1 = impl.execute(route, req1, context, null); final HttpResponse result2 = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_NOT_MODIFIED, result1.getStatusLine().getStatusCode()); assertEquals("etag", result1.getFirstHeader("Etag").getValue()); assertEquals(HttpStatus.SC_NOT_MODIFIED, result2.getStatusLine().getStatusCode()); assertEquals("etag", result2.getFirstHeader("Etag").getValue()); } @Test public void testNotModifiedResponseWithVaryUpdatesCacheEntryWhenNoEntity() throws Exception { final Date now = new Date(); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req1.addHeader("If-None-Match", "etag"); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req2.addHeader("If-None-Match", "etag"); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not modified"); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Cache-Control", "max-age=0"); resp1.setHeader("Etag", "etag"); resp1.setHeader("Vary", "Accept-Encoding"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not modified"); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader("Cache-Control", "max-age=0"); resp1.setHeader("Etag", "etag"); resp1.setHeader("Vary", "Accept-Encoding"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); final HttpResponse result1 = impl.execute(route, req1, context, null); final HttpResponse result2 = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_NOT_MODIFIED, result1.getStatusLine().getStatusCode()); assertEquals("etag", result1.getFirstHeader("Etag").getValue()); assertEquals(HttpStatus.SC_NOT_MODIFIED, result2.getStatusLine().getStatusCode()); assertEquals("etag", result2.getFirstHeader("Etag").getValue()); } @Test public void testDoesNotSend304ForNonConditionalRequest() throws Exception { final Date now = new Date(); final Date inOneMinute = new Date(System.currentTimeMillis() + 60000); impl = createCachingExecChain(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); req1.addHeader("If-None-Match", "etag"); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet( "http://foo.example.com/")); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not modified"); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Cache-Control", "public, max-age=60"); resp1.setHeader("Expires", DateUtils.formatDate(inOneMinute)); resp1.setHeader("Etag", "etag"); resp1.setHeader("Vary", "Accept-Encoding"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "Ok"); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader("Cache-Control", "public, max-age=60"); resp2.setHeader("Expires", DateUtils.formatDate(inOneMinute)); resp2.setHeader("Etag", "etag"); resp2.setHeader("Vary", "Accept-Encoding"); resp2.setEntity(HttpTestUtils.makeBody(128)); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2).anyTimes(); replayMocks(); final HttpResponse result1 = impl.execute(route, req1, context, null); final HttpResponse result2 = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_NOT_MODIFIED, result1.getStatusLine().getStatusCode()); assertNull(result1.getEntity()); assertEquals(HttpStatus.SC_OK, result2.getStatusLine().getStatusCode()); Assert.assertNotNull(result2.getEntity()); } @Test public void testUsesVirtualHostForCacheKey() throws Exception { final DummyBackend backend = new DummyBackend(); final HttpResponse response = HttpTestUtils.make200Response(); response.setHeader("Cache-Control", "max-age=3600"); backend.setResponse(response); impl = createCachingExecChain(backend, new BasicHttpCache(), CacheConfig.DEFAULT); impl.execute(route, request, context, null); assertEquals(1, backend.getExecutions()); context.setTargetHost(new HttpHost("bar.example.com")); impl.execute(route, request, context, null); assertEquals(2, backend.getExecutions()); impl.execute(route, request, context, null); assertEquals(2, backend.getExecutions()); } private IExpectationSetters backendExpectsAnyRequestAndReturn( final HttpResponse response) throws Exception { final CloseableHttpResponse resp = mockBackend.execute(EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock. isNull()); return EasyMock.expect(resp).andReturn(Proxies.enhanceResponse(response)); } protected IExpectationSetters backendExpectsRequestAndReturn( final HttpRequestWrapper request, final HttpResponse response) throws Exception { final CloseableHttpResponse resp = mockBackend.execute(EasyMock.isA(HttpRoute.class), EasyMock.eq(request), EasyMock.isA(HttpClientContext.class), EasyMock. isNull()); return EasyMock.expect(resp).andReturn(Proxies.enhanceResponse(response)); } protected IExpectationSetters backendExpectsRequestAndReturn( final HttpRequestWrapper request, final CloseableHttpResponse response) throws Exception { final CloseableHttpResponse resp = mockBackend.execute(EasyMock.isA(HttpRoute.class), EasyMock.eq(request), EasyMock.isA(HttpClientContext.class), EasyMock. isNull()); return EasyMock.expect(resp).andReturn(response); } protected IExpectationSetters backendExpectsAnyRequestAndThrows( final Throwable throwable) throws Exception { final CloseableHttpResponse resp = mockBackend.execute(EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock. isNull()); return EasyMock.expect(resp).andThrow(throwable); } protected IExpectationSetters backendCaptureRequestAndReturn( final Capture cap, final HttpResponse response) throws Exception { final CloseableHttpResponse resp = mockBackend.execute(EasyMock.isA(HttpRoute.class), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock. isNull()); return EasyMock.expect(resp).andReturn(Proxies.enhanceResponse(response)); } protected void getCacheEntryReturns(final HttpCacheEntry result) throws IOException { expect(mockCache.getCacheEntry(eq(host), eqRequest(request))).andReturn(result); } private void cacheInvalidatorWasCalled() throws IOException { mockCache .flushInvalidatedCacheEntriesFor((HttpHost) anyObject(), (HttpRequest) anyObject()); } protected void cacheEntryValidatable(final boolean b) { expect(mockValidityPolicy.isRevalidatable((HttpCacheEntry) anyObject())).andReturn(b) .anyTimes(); } protected void cacheEntryMustRevalidate(final boolean b) { expect(mockValidityPolicy.mustRevalidate(mockCacheEntry)).andReturn(b); } protected void cacheEntryProxyRevalidate(final boolean b) { expect(mockValidityPolicy.proxyRevalidate(mockCacheEntry)).andReturn(b); } protected void mayReturnStaleWhileRevalidating(final boolean b) { expect( mockValidityPolicy.mayReturnStaleWhileRevalidating((HttpCacheEntry) anyObject(), (Date) anyObject())).andReturn(b); } protected void conditionalRequestBuilderReturns(final HttpRequestWrapper validate) throws Exception { expect(mockConditionalRequestBuilder.buildConditionalRequest(request, entry)).andReturn( validate); } protected void requestPolicyAllowsCaching(final boolean allow) { expect(mockRequestPolicy.isServableFromCache((HttpRequest) anyObject())).andReturn(allow); } protected void cacheEntrySuitable(final boolean suitable) { expect( mockSuitabilityChecker.canCachedResponseBeUsed((HttpHost) anyObject(), (HttpRequest) anyObject(), (HttpCacheEntry) anyObject(), (Date) anyObject())) .andReturn(suitable); } private void entryHasStaleness(final long staleness) { expect( mockValidityPolicy.getStalenessSecs((HttpCacheEntry) anyObject(), (Date) anyObject())) .andReturn(staleness); } protected void responseIsGeneratedFromCache() { expect(mockResponseGenerator.generateResponse((HttpCacheEntry) anyObject())).andReturn( mockCachedResponse); } } ././@LongLink0100644 0000000 0000000 00000000177 12302131606 011632 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClientBuilder.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCac0100644 0000000 0000000 00000003457 12301751715 032254 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.junit.Test; public class TestCachingHttpClientBuilder { @Test public void testAsynchronousWorkersMax0() throws Exception { final CacheConfig cacheConfig = CacheConfig.custom() .setAsynchronousWorkersMax(0) .build(); // Asynchronous validation should be disabled but we should not get an // Exception CachingHttpClientBuilder.create().setCacheConfig(cacheConfig).build(); } @Test public void testNullCacheConfig() throws Exception { CachingHttpClientBuilder.create().setCacheConfig(null).build(); } } ././@LongLink0100644 0000000 0000000 00000000165 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCombinedEntity.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCom0100644 0000000 0000000 00000004476 12301751715 032306 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.ByteArrayInputStream; import org.apache.http.client.cache.Resource; import org.apache.http.util.EntityUtils; import org.easymock.classextension.EasyMock; import org.junit.Assert; import org.junit.Test; public class TestCombinedEntity { @Test public void testCombinedEntityBasics() throws Exception { final Resource resource = EasyMock.createNiceMock(Resource.class); EasyMock.expect(resource.getInputStream()).andReturn( new ByteArrayInputStream(new byte[] { 1, 2, 3, 4, 5 })); resource.dispose(); EasyMock.replay(resource); final ByteArrayInputStream instream = new ByteArrayInputStream(new byte[] { 6, 7, 8, 9, 10 }); final CombinedEntity entity = new CombinedEntity(resource, instream); Assert.assertEquals(-1, entity.getContentLength()); Assert.assertFalse(entity.isRepeatable()); Assert.assertTrue(entity.isStreaming()); final byte[] result = EntityUtils.toByteArray(entity); Assert.assertArrayEquals(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, result); EasyMock.verify(resource); } } ././@LongLink0100644 0000000 0000000 00000000200 12302131606 011615 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestConditionalRequestBuilder.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCon0100644 0000000 0000000 00000035442 12301751716 032305 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpRequest; import org.apache.http.HttpVersion; import org.apache.http.ProtocolException; import org.apache.http.client.cache.HeaderConstants; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.utils.DateUtils; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpRequest; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestConditionalRequestBuilder { private ConditionalRequestBuilder impl; private HttpRequestWrapper request; private HttpCacheEntry entry; @Before public void setUp() throws Exception { impl = new ConditionalRequestBuilder(); request = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); entry = HttpTestUtils.makeCacheEntry(); } @Test public void testBuildConditionalRequestWithLastModified() throws ProtocolException { final String theMethod = "GET"; final String theUri = "/theuri"; final String lastModified = "this is my last modified date"; final HttpRequest request = new BasicHttpRequest(theMethod, theUri); request.addHeader("Accept-Encoding", "gzip"); final HttpRequestWrapper requestWrapper = HttpRequestWrapper.wrap(request); final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(new Date())), new BasicHeader("Last-Modified", lastModified) }; final HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(headers); final HttpRequestWrapper newRequest = impl.buildConditionalRequest(requestWrapper, cacheEntry); Assert.assertNotSame(request, newRequest); Assert.assertEquals(theMethod, newRequest.getRequestLine().getMethod()); Assert.assertEquals(theUri, newRequest.getRequestLine().getUri()); Assert.assertEquals(request.getRequestLine().getProtocolVersion(), newRequest .getRequestLine().getProtocolVersion()); Assert.assertEquals(2, newRequest.getAllHeaders().length); Assert.assertEquals("Accept-Encoding", newRequest.getAllHeaders()[0].getName()); Assert.assertEquals("gzip", newRequest.getAllHeaders()[0].getValue()); Assert.assertEquals("If-Modified-Since", newRequest.getAllHeaders()[1].getName()); Assert.assertEquals(lastModified, newRequest.getAllHeaders()[1].getValue()); } @Test public void testConditionalRequestForEntryWithLastModifiedAndEtagIncludesBothAsValidators() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Date twentySecondsAgo = new Date(now.getTime() - 20 * 1000L); final String lmDate = DateUtils.formatDate(twentySecondsAgo); final String etag = "\"etag\""; final Header[] headers = { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("Last-Modified", lmDate), new BasicHeader("ETag", etag) }; final HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); final HttpRequestWrapper requestWrapper = HttpRequestWrapper.wrap(request); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); final HttpRequest result = impl.buildConditionalRequest(requestWrapper, entry); Assert.assertEquals(lmDate, result.getFirstHeader("If-Modified-Since").getValue()); Assert.assertEquals(etag, result.getFirstHeader("If-None-Match").getValue()); } @Test public void testBuildConditionalRequestWithETag() throws ProtocolException { final String theMethod = "GET"; final String theUri = "/theuri"; final String theETag = "this is my eTag"; final HttpRequest request = new BasicHttpRequest(theMethod, theUri); request.addHeader("Accept-Encoding", "gzip"); final HttpRequestWrapper requestWrapper = HttpRequestWrapper.wrap(request); final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatDate(new Date())), new BasicHeader("Last-Modified", DateUtils.formatDate(new Date())), new BasicHeader("ETag", theETag) }; final HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(headers); final HttpRequest newRequest = impl.buildConditionalRequest(requestWrapper, cacheEntry); Assert.assertNotSame(request, newRequest); Assert.assertEquals(theMethod, newRequest.getRequestLine().getMethod()); Assert.assertEquals(theUri, newRequest.getRequestLine().getUri()); Assert.assertEquals(request.getRequestLine().getProtocolVersion(), newRequest .getRequestLine().getProtocolVersion()); Assert.assertEquals(3, newRequest.getAllHeaders().length); Assert.assertEquals("Accept-Encoding", newRequest.getAllHeaders()[0].getName()); Assert.assertEquals("gzip", newRequest.getAllHeaders()[0].getValue()); Assert.assertEquals("If-None-Match", newRequest.getAllHeaders()[1].getName()); Assert.assertEquals(theETag, newRequest.getAllHeaders()[1].getValue()); } @Test public void testCacheEntryWithMustRevalidateDoesEndToEndRevalidation() throws Exception { final HttpRequest request = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); final HttpRequestWrapper requestWrapper = HttpRequestWrapper.wrap(request); final Date now = new Date(); final Date elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Date nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); final Header[] cacheEntryHeaders = new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("ETag", "\"etag\""), new BasicHeader("Cache-Control","max-age=5, must-revalidate") }; final HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(elevenSecondsAgo, nineSecondsAgo, cacheEntryHeaders); final HttpRequest result = impl.buildConditionalRequest(requestWrapper, cacheEntry); boolean foundMaxAge0 = false; for(final Header h : result.getHeaders("Cache-Control")) { for(final HeaderElement elt : h.getElements()) { if ("max-age".equalsIgnoreCase(elt.getName()) && "0".equals(elt.getValue())) { foundMaxAge0 = true; } } } Assert.assertTrue(foundMaxAge0); } @Test public void testCacheEntryWithProxyRevalidateDoesEndToEndRevalidation() throws Exception { final HttpRequest request = new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1); final HttpRequestWrapper requestWrapper = HttpRequestWrapper.wrap(request); final Date now = new Date(); final Date elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Date nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); final Header[] cacheEntryHeaders = new Header[] { new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)), new BasicHeader("ETag", "\"etag\""), new BasicHeader("Cache-Control","max-age=5, proxy-revalidate") }; final HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(elevenSecondsAgo, nineSecondsAgo, cacheEntryHeaders); final HttpRequest result = impl.buildConditionalRequest(requestWrapper, cacheEntry); boolean foundMaxAge0 = false; for(final Header h : result.getHeaders("Cache-Control")) { for(final HeaderElement elt : h.getElements()) { if ("max-age".equalsIgnoreCase(elt.getName()) && "0".equals(elt.getValue())) { foundMaxAge0 = true; } } } Assert.assertTrue(foundMaxAge0); } @Test public void testBuildUnconditionalRequestUsesGETMethod() throws Exception { final HttpRequest result = impl.buildUnconditionalRequest(request, entry); Assert.assertEquals("GET", result.getRequestLine().getMethod()); } @Test public void testBuildUnconditionalRequestUsesRequestUri() throws Exception { final String uri = "/theURI"; request = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", uri, HttpVersion.HTTP_1_1)); final HttpRequest result = impl.buildUnconditionalRequest(request, entry); Assert.assertEquals(uri, result.getRequestLine().getUri()); } @Test public void testBuildUnconditionalRequestUsesHTTP_1_1() throws Exception { final HttpRequest result = impl.buildUnconditionalRequest(request, entry); Assert.assertEquals(HttpVersion.HTTP_1_1, result.getProtocolVersion()); } @Test public void testBuildUnconditionalRequestAddsCacheControlNoCache() throws Exception { final HttpRequest result = impl.buildUnconditionalRequest(request, entry); boolean ccNoCacheFound = false; for(final Header h : result.getHeaders("Cache-Control")) { for(final HeaderElement elt : h.getElements()) { if ("no-cache".equals(elt.getName())) { ccNoCacheFound = true; } } } Assert.assertTrue(ccNoCacheFound); } @Test public void testBuildUnconditionalRequestAddsPragmaNoCache() throws Exception { final HttpRequest result = impl.buildUnconditionalRequest(request, entry); boolean ccNoCacheFound = false; for(final Header h : result.getHeaders("Pragma")) { for(final HeaderElement elt : h.getElements()) { if ("no-cache".equals(elt.getName())) { ccNoCacheFound = true; } } } Assert.assertTrue(ccNoCacheFound); } @Test public void testBuildUnconditionalRequestDoesNotUseIfRange() throws Exception { request.addHeader("If-Range","\"etag\""); final HttpRequest result = impl.buildUnconditionalRequest(request, entry); Assert.assertNull(result.getFirstHeader("If-Range")); } @Test public void testBuildUnconditionalRequestDoesNotUseIfMatch() throws Exception { request.addHeader("If-Match","\"etag\""); final HttpRequest result = impl.buildUnconditionalRequest(request, entry); Assert.assertNull(result.getFirstHeader("If-Match")); } @Test public void testBuildUnconditionalRequestDoesNotUseIfNoneMatch() throws Exception { request.addHeader("If-None-Match","\"etag\""); final HttpRequest result = impl.buildUnconditionalRequest(request, entry); Assert.assertNull(result.getFirstHeader("If-None-Match")); } @Test public void testBuildUnconditionalRequestDoesNotUseIfUnmodifiedSince() throws Exception { request.addHeader("If-Unmodified-Since", DateUtils.formatDate(new Date())); final HttpRequest result = impl.buildUnconditionalRequest(request, entry); Assert.assertNull(result.getFirstHeader("If-Unmodified-Since")); } @Test public void testBuildUnconditionalRequestDoesNotUseIfModifiedSince() throws Exception { request.addHeader("If-Modified-Since", DateUtils.formatDate(new Date())); final HttpRequest result = impl.buildUnconditionalRequest(request, entry); Assert.assertNull(result.getFirstHeader("If-Modified-Since")); } @Test public void testBuildUnconditionalRequestCarriesOtherRequestHeaders() throws Exception { request.addHeader("User-Agent","MyBrowser/1.0"); final HttpRequest result = impl.buildUnconditionalRequest(request, entry); Assert.assertEquals("MyBrowser/1.0", result.getFirstHeader("User-Agent").getValue()); } @Test public void testBuildConditionalRequestFromVariants() throws Exception { final String etag1 = "\"123\""; final String etag2 = "\"456\""; final String etag3 = "\"789\""; final Map variantEntries = new HashMap(); variantEntries.put(etag1, new Variant("A","B",HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("ETag", etag1) }))); variantEntries.put(etag2, new Variant("C","D",HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("ETag", etag2) }))); variantEntries.put(etag3, new Variant("E","F",HttpTestUtils.makeCacheEntry(new Header[] { new BasicHeader("ETag", etag3) }))); final HttpRequest conditional = impl.buildConditionalRequestFromVariants(request, variantEntries); // seems like a lot of work, but necessary, check for existence and exclusiveness String ifNoneMatch = conditional.getFirstHeader(HeaderConstants.IF_NONE_MATCH).getValue(); Assert.assertTrue(ifNoneMatch.contains(etag1)); Assert.assertTrue(ifNoneMatch.contains(etag2)); Assert.assertTrue(ifNoneMatch.contains(etag3)); ifNoneMatch = ifNoneMatch.replace(etag1, ""); ifNoneMatch = ifNoneMatch.replace(etag2, ""); ifNoneMatch = ifNoneMatch.replace(etag3, ""); ifNoneMatch = ifNoneMatch.replace(",",""); ifNoneMatch = ifNoneMatch.replace(" ", ""); Assert.assertEquals(ifNoneMatch, ""); } } ././@LongLink0100644 0000000 0000000 00000000172 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestDefaultFailureCache.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestDef0100644 0000000 0000000 00000004630 12301751715 032256 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.junit.Assert; import org.junit.Test; public class TestDefaultFailureCache { private static final String IDENTIFIER = "some-identifier"; private FailureCache failureCache = new DefaultFailureCache(); @Test public void testResetErrorCount() { failureCache.increaseErrorCount(IDENTIFIER); failureCache.resetErrorCount(IDENTIFIER); final int errorCount = failureCache.getErrorCount(IDENTIFIER); Assert.assertEquals(0, errorCount); } @Test public void testIncrementErrorCount() { failureCache.increaseErrorCount(IDENTIFIER); failureCache.increaseErrorCount(IDENTIFIER); failureCache.increaseErrorCount(IDENTIFIER); final int errorCount = failureCache.getErrorCount(IDENTIFIER); Assert.assertEquals(3, errorCount); } @Test public void testMaxSize() { failureCache = new DefaultFailureCache(3); failureCache.increaseErrorCount("a"); failureCache.increaseErrorCount("b"); failureCache.increaseErrorCount("c"); failureCache.increaseErrorCount("d"); final int errorCount = failureCache.getErrorCount("a"); Assert.assertEquals(0, errorCount); } } ././@LongLink0100644 0000000 0000000 00000000216 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestExponentialBackingOffSchedulingStrategy.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestExp0100644 0000000 0000000 00000014643 12301751713 032317 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.apache.http.HttpHost; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.impl.execchain.ClientExecChain; import org.apache.http.message.BasicHttpRequest; import org.easymock.EasyMock; import org.junit.Before; import org.junit.Test; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class TestExponentialBackingOffSchedulingStrategy { private ScheduledExecutorService mockExecutor; private ExponentialBackOffSchedulingStrategy impl; @Before public void setUp() { mockExecutor = EasyMock.createMock(ScheduledExecutorService.class); impl = new ExponentialBackOffSchedulingStrategy( mockExecutor, ExponentialBackOffSchedulingStrategy.DEFAULT_BACK_OFF_RATE, ExponentialBackOffSchedulingStrategy.DEFAULT_INITIAL_EXPIRY_IN_MILLIS, ExponentialBackOffSchedulingStrategy.DEFAULT_MAX_EXPIRY_IN_MILLIS ); } @Test public void testScheduleWithoutPreviousError() { final AsynchronousValidationRequest request = createAsynchronousValidationRequest(withErrorCount(0)); expectRequestScheduledWithoutDelay(request); replayMocks(); impl.schedule(request); verifyMocks(); } @Test public void testScheduleWithOneFailedAttempt() { final AsynchronousValidationRequest request = createAsynchronousValidationRequest(withErrorCount(1)); expectRequestScheduledWithDelay(request, TimeUnit.SECONDS.toMillis(6)); replayMocks(); impl.schedule(request); verifyMocks(); } @Test public void testScheduleWithTwoFailedAttempts() { final AsynchronousValidationRequest request = createAsynchronousValidationRequest(withErrorCount(2)); expectRequestScheduledWithDelay(request, TimeUnit.SECONDS.toMillis(60)); replayMocks(); impl.schedule(request); verifyMocks(); } @Test public void testScheduleWithThreeFailedAttempts() { final AsynchronousValidationRequest request = createAsynchronousValidationRequest(withErrorCount(3)); expectRequestScheduledWithDelay(request, TimeUnit.SECONDS.toMillis(600)); replayMocks(); impl.schedule(request); verifyMocks(); } @Test public void testScheduleWithFourFailedAttempts() { final AsynchronousValidationRequest request = createAsynchronousValidationRequest(withErrorCount(4)); expectRequestScheduledWithDelay(request, TimeUnit.SECONDS.toMillis(6000)); replayMocks(); impl.schedule(request); verifyMocks(); } @Test public void testScheduleWithFiveFailedAttempts() { final AsynchronousValidationRequest request = createAsynchronousValidationRequest(withErrorCount(5)); expectRequestScheduledWithDelay(request, TimeUnit.SECONDS.toMillis(60000)); replayMocks(); impl.schedule(request); verifyMocks(); } @Test public void testScheduleWithSixFailedAttempts() { final AsynchronousValidationRequest request = createAsynchronousValidationRequest(withErrorCount(6)); expectRequestScheduledWithDelay(request, TimeUnit.SECONDS.toMillis(86400)); replayMocks(); impl.schedule(request); verifyMocks(); } @Test public void testScheduleWithMaxNumberOfFailedAttempts() { final AsynchronousValidationRequest request = createAsynchronousValidationRequest(withErrorCount(Integer.MAX_VALUE)); expectRequestScheduledWithDelay(request, TimeUnit.SECONDS.toMillis(86400)); replayMocks(); impl.schedule(request); verifyMocks(); } private void expectRequestScheduledWithoutDelay(final AsynchronousValidationRequest request) { expectRequestScheduledWithDelay(request, 0); } private void expectRequestScheduledWithDelay(final AsynchronousValidationRequest request, final long delayInMillis) { EasyMock.expect(mockExecutor.schedule(request, delayInMillis, TimeUnit.MILLISECONDS)).andReturn(null); } private void replayMocks() { EasyMock.replay(mockExecutor); } private void verifyMocks() { EasyMock.verify(mockExecutor); } private AsynchronousValidationRequest createAsynchronousValidationRequest(final int errorCount) { final ClientExecChain clientExecChain = EasyMock.createNiceMock(ClientExecChain.class); final CachingExec cachingHttpClient = new CachingExec(clientExecChain); final AsynchronousValidator mockValidator = new AsynchronousValidator(impl); final HttpRoute httpRoute = new HttpRoute(new HttpHost("foo.example.com")); final HttpRequestWrapper httpRequestWrapper = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/")); final HttpClientContext httpClientContext = new HttpClientContext(); return new AsynchronousValidationRequest(mockValidator, cachingHttpClient, httpRoute, httpRequestWrapper, httpClientContext, null, null, "identifier", errorCount); } private static int withErrorCount(final int errorCount) { return errorCount; } } ././@LongLink0100644 0000000 0000000 00000000200 12302131606 011615 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestHttpCacheEntrySerializers.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestHtt0100644 0000000 0000000 00000013211 12301751715 032312 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.commons.codec.binary.Base64; import org.apache.http.Header; import org.apache.http.ProtocolVersion; import org.apache.http.StatusLine; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheEntrySerializer; import org.apache.http.client.cache.Resource; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicStatusLine; import org.junit.Before; import org.junit.Test; public class TestHttpCacheEntrySerializers { private static final Charset UTF8 = Charset.forName("UTF-8"); private HttpCacheEntrySerializer impl; @Before public void setUp() { impl = new DefaultHttpCacheEntrySerializer(); } @Test public void canSerializeEntriesWithVariantMaps() throws Exception { readWriteVerify(makeCacheEntryWithVariantMap()); } public void readWriteVerify(final HttpCacheEntry writeEntry) throws IOException { // write the entry final ByteArrayOutputStream out = new ByteArrayOutputStream(); impl.writeTo(writeEntry, out); // read the entry final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); final HttpCacheEntry readEntry = impl.readFrom(in); // compare assertTrue(areEqual(readEntry, writeEntry)); } private HttpCacheEntry makeCacheEntryWithVariantMap() throws UnsupportedEncodingException { final Header[] headers = new Header[5]; for (int i = 0; i < headers.length; i++) { headers[i] = new BasicHeader("header" + i, "value" + i); } final String body = "Lorem ipsum dolor sit amet"; final ProtocolVersion pvObj = new ProtocolVersion("HTTP", 1, 1); final StatusLine slObj = new BasicStatusLine(pvObj, 200, "ok"); final Map variantMap = new HashMap(); variantMap.put("test variant 1","true"); variantMap.put("test variant 2","true"); final HttpCacheEntry cacheEntry = new HttpCacheEntry(new Date(), new Date(), slObj, headers, new HeapResource(Base64.decodeBase64(body .getBytes(UTF8.name()))), variantMap); return cacheEntry; } private boolean areEqual(final HttpCacheEntry one, final HttpCacheEntry two) throws IOException { // dates are only stored with second precision, so scrub milliseconds if (!((one.getRequestDate().getTime() / 1000) == (two.getRequestDate() .getTime() / 1000))) { return false; } if (!((one.getResponseDate().getTime() / 1000) == (two .getResponseDate().getTime() / 1000))) { return false; } if (!one.getProtocolVersion().equals(two.getProtocolVersion())) { return false; } final byte[] onesByteArray = resourceToBytes(one.getResource()); final byte[] twosByteArray = resourceToBytes(two.getResource()); if (!Arrays.equals(onesByteArray,twosByteArray)) { return false; } final Header[] oneHeaders = one.getAllHeaders(); final Header[] twoHeaders = two.getAllHeaders(); if (!(oneHeaders.length == twoHeaders.length)) { return false; } for (int i = 0; i < oneHeaders.length; i++) { if (!oneHeaders[i].getName().equals(twoHeaders[i].getName())) { return false; } if (!oneHeaders[i].getValue().equals(twoHeaders[i].getValue())) { return false; } } return true; } private byte[] resourceToBytes(final Resource res) throws IOException { final InputStream inputStream = res.getInputStream(); final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); int readBytes; final byte[] bytes = new byte[8096]; while ((readBytes = inputStream.read(bytes)) > 0) { outputStream.write(bytes, 0, readBytes); } final byte[] byteData = outputStream.toByteArray(); inputStream.close(); outputStream.close(); return byteData; } } ././@LongLink0100644 0000000 0000000 00000000176 12302131606 011631 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestHttpCacheJiraNumber1147.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestHtt0100644 0000000 0000000 00000012673 12301751715 032325 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.File; import java.util.Date; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.client.cache.ResourceFactory; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.DateUtils; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.impl.execchain.ClientExecChain; import org.apache.http.message.BasicHttpResponse; import org.easymock.EasyMock; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestHttpCacheJiraNumber1147 { private File cacheDir; private void removeCache() { if (this.cacheDir != null) { final File[] files = this.cacheDir.listFiles(); for (final File cacheFile : files) { cacheFile.delete(); } this.cacheDir.delete(); this.cacheDir = null; } } @Before public void setUp() throws Exception { cacheDir = File.createTempFile("cachedir", ""); if (cacheDir.exists()) { cacheDir.delete(); } cacheDir.mkdir(); } @After public void cleanUp() { removeCache(); } @Test public void testIssue1147() throws Exception { final CacheConfig cacheConfig = CacheConfig.custom() .setSharedCache(true) .setMaxObjectSize(262144) //256kb .build(); final ResourceFactory resourceFactory = new FileResourceFactory(cacheDir); final HttpCacheStorage httpCacheStorage = new ManagedHttpCacheStorage(cacheConfig); final ClientExecChain backend = EasyMock.createNiceMock(ClientExecChain.class); final HttpRequestWrapper get = HttpRequestWrapper.wrap(new HttpGet("http://somehost/")); final HttpClientContext context = HttpClientContext.create(); final HttpHost target = new HttpHost("somehost"); final HttpRoute route = new HttpRoute(target); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); response.setEntity(HttpTestUtils.makeBody(128)); response.setHeader("Content-Length", "128"); response.setHeader("ETag", "\"etag\""); response.setHeader("Cache-Control", "public, max-age=3600"); response.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo)); EasyMock.expect(backend.execute( EasyMock.eq(route), EasyMock.isA(HttpRequestWrapper.class), EasyMock.same(context), EasyMock.isNull())).andReturn(Proxies.enhanceResponse(response)); EasyMock.replay(backend); final BasicHttpCache cache = new BasicHttpCache(resourceFactory, httpCacheStorage, cacheConfig); final ClientExecChain t = createCachingExecChain(backend, cache, cacheConfig); final HttpResponse response1 = t.execute(route, get, context, null); Assert.assertEquals(200, response1.getStatusLine().getStatusCode()); IOUtils.consume(response1.getEntity()); EasyMock.verify(backend); removeCache(); EasyMock.reset(backend); EasyMock.expect(backend.execute( EasyMock.eq(route), EasyMock.isA(HttpRequestWrapper.class), EasyMock.same(context), EasyMock.isNull())).andReturn(Proxies.enhanceResponse(response)); EasyMock.replay(backend); final HttpResponse response2 = t.execute(route, get, context, null); Assert.assertEquals(200, response2.getStatusLine().getStatusCode()); IOUtils.consume(response2.getEntity()); EasyMock.verify(backend); } protected ClientExecChain createCachingExecChain(final ClientExecChain backend, final BasicHttpCache cache, final CacheConfig config) { return new CachingExec(backend, cache, config); } } ././@LongLink0100644 0000000 0000000 00000000202 12302131606 011617 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestImmediateSchedulingStrategy.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestImm0100644 0000000 0000000 00000004262 12301751715 032303 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.easymock.classextension.EasyMock; import org.junit.Before; import org.junit.Test; import java.util.concurrent.ExecutorService; public class TestImmediateSchedulingStrategy { private ExecutorService mockExecutor; private AsynchronousValidationRequest mockRevalidationRequest; private SchedulingStrategy schedulingStrategy; @Before public void setUp() { mockExecutor = EasyMock.createMock(ExecutorService.class); mockRevalidationRequest = EasyMock.createNiceMock(AsynchronousValidationRequest.class); schedulingStrategy = new ImmediateSchedulingStrategy(mockExecutor); } @Test public void testRequestScheduledImmediately() { mockExecutor.execute(mockRevalidationRequest); EasyMock.replay(mockExecutor); EasyMock.replay(mockRevalidationRequest); schedulingStrategy.schedule(mockRevalidationRequest); EasyMock.verify(mockExecutor); EasyMock.verify(mockRevalidationRequest); } }././@LongLink0100644 0000000 0000000 00000000176 12302131606 011631 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolAllowedBehavior.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestPro0100644 0000000 0000000 00000007431 12301751713 032320 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.net.SocketTimeoutException; import java.util.Date; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.utils.DateUtils; import org.apache.http.message.BasicHttpRequest; import org.junit.Assert; import org.junit.Test; /** * This class tests behavior that is allowed (MAY) by the HTTP/1.1 protocol * specification and for which we have implemented the behavior in the * {@link CachingHttpClient}. */ public class TestProtocolAllowedBehavior extends AbstractProtocolTest { @Test public void testNonSharedCacheReturnsStaleResponseWhenRevalidationFailsForProxyRevalidate() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET","/", HttpVersion.HTTP_1_1)); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); originResponse.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); originResponse.setHeader("Cache-Control","max-age=5,proxy-revalidate"); originResponse.setHeader("Etag","\"etag\""); backendExpectsAnyRequest().andReturn(originResponse); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET","/", HttpVersion.HTTP_1_1)); backendExpectsAnyRequest().andThrow(new SocketTimeoutException()); replayMocks(); behaveAsNonSharedCache(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode()); } @Test public void testNonSharedCacheMayCacheResponsesWithCacheControlPrivate() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET","/", HttpVersion.HTTP_1_1)); originResponse.setHeader("Cache-Control","private,max-age=3600"); backendExpectsAnyRequest().andReturn(originResponse); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET","/", HttpVersion.HTTP_1_1)); replayMocks(); behaveAsNonSharedCache(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode()); } } ././@LongLink0100644 0000000 0000000 00000000171 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolDeviations.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestPro0100644 0000000 0000000 00000041063 12301751713 032317 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.Date; import java.util.Random; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.ProtocolVersion; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.cache.HttpCacheContext; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.client.utils.DateUtils; import org.apache.http.impl.execchain.ClientExecChain; import org.apache.http.message.BasicHttpEntityEnclosingRequest; import org.apache.http.message.BasicHttpRequest; import org.apache.http.message.BasicHttpResponse; import org.easymock.Capture; import org.easymock.classextension.EasyMock; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; /** * We are a conditionally-compliant HTTP/1.1 client with a cache. However, a lot * of the rules for proxies apply to us, as far as proper operation of the * requests that pass through us. Generally speaking, we want to make sure that * any response returned from our HttpClient.execute() methods is conditionally * compliant with the rules for an HTTP/1.1 server, and that any requests we * pass downstream to the backend HttpClient are are conditionally compliant * with the rules for an HTTP/1.1 client. * * There are some cases where strictly behaving as a compliant caching proxy * would result in strange behavior, since we're attached as part of a client * and are expected to be a drop-in replacement. The test cases captured here * document the places where we differ from the HTTP RFC. */ public class TestProtocolDeviations { private static ProtocolVersion HTTP_1_1 = new ProtocolVersion("HTTP", 1, 1); private static final int MAX_BYTES = 1024; private static final int MAX_ENTRIES = 100; private final int entityLength = 128; private HttpHost host; private HttpRoute route; private HttpEntity body; private HttpEntity mockEntity; private ClientExecChain mockBackend; private HttpCache mockCache; private HttpRequest request; private HttpCacheContext context; private CloseableHttpResponse originResponse; private ClientExecChain impl; @Before public void setUp() { host = new HttpHost("foo.example.com"); route = new HttpRoute(host); body = makeBody(entityLength); request = new BasicHttpRequest("GET", "/foo", HTTP_1_1); context = HttpCacheContext.create(); context.setTargetHost(host); originResponse = Proxies.enhanceResponse(make200Response()); final CacheConfig config = CacheConfig.custom() .setMaxCacheEntries(MAX_ENTRIES) .setMaxObjectSize(MAX_BYTES) .build(); final HttpCache cache = new BasicHttpCache(config); mockBackend = EasyMock.createNiceMock(ClientExecChain.class); mockEntity = EasyMock.createNiceMock(HttpEntity.class); mockCache = EasyMock.createNiceMock(HttpCache.class); impl = createCachingExecChain(mockBackend, cache, config); } protected ClientExecChain createCachingExecChain( final ClientExecChain backend, final HttpCache cache, final CacheConfig config) { return new CachingExec(backend, cache, config); } private HttpResponse make200Response() { final HttpResponse out = new BasicHttpResponse(HTTP_1_1, HttpStatus.SC_OK, "OK"); out.setHeader("Date", DateUtils.formatDate(new Date())); out.setHeader("Server", "MockOrigin/1.0"); out.setEntity(makeBody(128)); return out; } private void replayMocks() { EasyMock.replay(mockBackend); EasyMock.replay(mockCache); EasyMock.replay(mockEntity); } private void verifyMocks() { EasyMock.verify(mockBackend); EasyMock.verify(mockCache); EasyMock.verify(mockEntity); } private HttpEntity makeBody(final int nbytes) { final byte[] bytes = new byte[nbytes]; new Random().nextBytes(bytes); return new ByteArrayEntity(bytes); } public static HttpRequest eqRequest(final HttpRequest in) { org.easymock.EasyMock.reportMatcher(new RequestEquivalent(in)); return null; } /* * "For compatibility with HTTP/1.0 applications, HTTP/1.1 requests * containing a message-body MUST include a valid Content-Length header * field unless the server is known to be HTTP/1.1 compliant. If a request * contains a message-body and a Content-Length is not given, the server * SHOULD respond with 400 (bad request) if it cannot determine the length * of the message, or with 411 (length required) if it wishes to insist on * receiving a valid Content-Length." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4 * * 8/23/2010 JRC - This test has been moved to Ignore. The caching client * was set to return status code 411 on a missing content-length header when * a request had a body. It seems that somewhere deeper in the client stack * this header is added automatically for us - so the caching client shouldn't * specifically be worried about this requirement. */ @Ignore public void testHTTP1_1RequestsWithBodiesOfKnownLengthMustHaveContentLength() throws Exception { final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/", HTTP_1_1); post.setEntity(mockEntity); replayMocks(); final HttpResponse response = impl.execute(route, HttpRequestWrapper.wrap(post), context, null); verifyMocks(); Assert .assertEquals(HttpStatus.SC_LENGTH_REQUIRED, response.getStatusLine() .getStatusCode()); } /* * Discussion: if an incoming request has a body, but the HttpEntity * attached has an unknown length (meaning entity.getContentLength() is * negative), we have two choices if we want to be conditionally compliant. * (1) we can slurp the whole body into a bytearray and compute its length * before sending; or (2) we can push responsibility for (1) back onto the * client by just generating a 411 response * * There is a third option, which is that we delegate responsibility for (1) * onto the backend HttpClient, but because that is an injected dependency, * we can't rely on it necessarily being conditionally compliant with * HTTP/1.1. Currently, option (2) seems like the safest bet, as this * exposes to the client application that the slurping required for (1) * needs to happen in order to compute the content length. * * In any event, this test just captures the behavior required. * * 8/23/2010 JRC - This test has been moved to Ignore. The caching client * was set to return status code 411 on a missing content-length header when * a request had a body. It seems that somewhere deeper in the client stack * this header is added automatically for us - so the caching client shouldn't * specifically be worried about this requirement. */ @Ignore public void testHTTP1_1RequestsWithUnknownBodyLengthAreRejectedOrHaveContentLengthAdded() throws Exception { final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/", HTTP_1_1); final byte[] bytes = new byte[128]; new Random().nextBytes(bytes); final HttpEntity mockBody = EasyMock.createMockBuilder(ByteArrayEntity.class).withConstructor( new Object[] { bytes }).addMockedMethods("getContentLength").createNiceMock(); org.easymock.EasyMock.expect(mockBody.getContentLength()).andReturn(-1L).anyTimes(); post.setEntity(mockBody); final Capture reqCap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(reqCap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( originResponse).times(0, 1); replayMocks(); EasyMock.replay(mockBody); final HttpResponse result = impl.execute(route, HttpRequestWrapper.wrap(post), context, null); verifyMocks(); EasyMock.verify(mockBody); if (reqCap.hasCaptured()) { // backend request was made final HttpRequest forwarded = reqCap.getValue(); Assert.assertNotNull(forwarded.getFirstHeader("Content-Length")); } else { final int status = result.getStatusLine().getStatusCode(); Assert.assertTrue(HttpStatus.SC_LENGTH_REQUIRED == status || HttpStatus.SC_BAD_REQUEST == status); } } /* * "If the OPTIONS request includes an entity-body (as indicated by the * presence of Content-Length or Transfer-Encoding), then the media type * MUST be indicated by a Content-Type field." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2 */ @Test public void testOPTIONSRequestsWithBodiesAndNoContentTypeHaveOneSupplied() throws Exception { final BasicHttpEntityEnclosingRequest options = new BasicHttpEntityEnclosingRequest("OPTIONS", "/", HTTP_1_1); options.setEntity(body); options.setHeader("Content-Length", "1"); final Capture reqCap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(reqCap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, HttpRequestWrapper.wrap(options), context, null); verifyMocks(); final HttpRequest forwarded = reqCap.getValue(); Assert.assertTrue(forwarded instanceof HttpEntityEnclosingRequest); final HttpEntityEnclosingRequest reqWithBody = (HttpEntityEnclosingRequest) forwarded; final HttpEntity reqBody = reqWithBody.getEntity(); Assert.assertNotNull(reqBody); Assert.assertNotNull(reqBody.getContentType()); } /* * "10.2.7 206 Partial Content ... The request MUST have included a Range * header field (section 14.35) indicating the desired range, and MAY have * included an If-Range header field (section 14.27) to make the request * conditional." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7 */ @Test public void testPartialContentIsNotReturnedToAClientThatDidNotAskForIt() throws Exception { // tester's note: I don't know what the cache will *do* in // this situation, but it better not just pass the response // on. request.removeHeaders("Range"); originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content")); originResponse.setHeader("Content-Range", "bytes 0-499/1234"); originResponse.setEntity(makeBody(500)); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); try { final HttpResponse result = impl.execute(route, HttpRequestWrapper.wrap(request), context, null); Assert.assertTrue(HttpStatus.SC_PARTIAL_CONTENT != result.getStatusLine() .getStatusCode()); } catch (final ClientProtocolException acceptableBehavior) { // this is probably ok } } /* * "10.4.2 401 Unauthorized ... The response MUST include a WWW-Authenticate * header field (section 14.47) containing a challenge applicable to the * requested resource." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2 */ @Test public void testPassesOnOrigin401ResponseWithoutWWWAuthenticateHeader() throws Exception { originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HTTP_1_1, 401, "Unauthorized")); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, HttpRequestWrapper.wrap(request), context, null); verifyMocks(); Assert.assertSame(originResponse, result); } /* * "10.4.6 405 Method Not Allowed ... The response MUST include an Allow * header containing a list of valid methods for the requested resource. * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2 */ @Test public void testPassesOnOrigin405WithoutAllowHeader() throws Exception { originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HTTP_1_1, 405, "Method Not Allowed")); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, HttpRequestWrapper.wrap(request), context, null); verifyMocks(); Assert.assertSame(originResponse, result); } /* * "10.4.8 407 Proxy Authentication Required ... The proxy MUST return a * Proxy-Authenticate header field (section 14.33) containing a challenge * applicable to the proxy for the requested resource." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8 */ @Test public void testPassesOnOrigin407WithoutAProxyAuthenticateHeader() throws Exception { originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HTTP_1_1, 407, "Proxy Authentication Required")); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, HttpRequestWrapper.wrap(request), context, null); verifyMocks(); Assert.assertSame(originResponse, result); } } ././@LongLink0100644 0000000 0000000 00000000176 12302131606 011631 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestPro0100644 0000000 0000000 00000224015 12301751715 032321 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.util.Arrays; import java.util.Date; import java.util.List; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.DateUtils; import org.apache.http.message.BasicHttpEntityEnclosingRequest; import org.apache.http.message.BasicHttpRequest; import org.apache.http.message.BasicHttpResponse; import org.easymock.Capture; import org.easymock.EasyMock; import org.junit.Before; import org.junit.Test; /* * This test class captures functionality required to achieve unconditional * compliance with the HTTP/1.1 spec, i.e. all the SHOULD, SHOULD NOT, * RECOMMENDED, and NOT RECOMMENDED behaviors. */ public class TestProtocolRecommendations extends AbstractProtocolTest { private Date now; private Date tenSecondsAgo; private Date twoMinutesAgo; @Override @Before public void setUp() { super.setUp(); now = new Date(); tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); twoMinutesAgo = new Date(now.getTime() - 2 * 60 * 1000L); } /* "identity: The default (identity) encoding; the use of no * transformation whatsoever. This content-coding is used only in the * Accept-Encoding header, and SHOULD NOT be used in the * Content-Encoding header." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5 */ @Test public void testIdentityCodingIsNotUsedInContentEncodingHeader() throws Exception { originResponse.setHeader("Content-Encoding", "identity"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); boolean foundIdentity = false; for(final Header h : result.getHeaders("Content-Encoding")) { for(final HeaderElement elt : h.getElements()) { if ("identity".equalsIgnoreCase(elt.getName())) { foundIdentity = true; } } } assertFalse(foundIdentity); } /* * "304 Not Modified. ... If the conditional GET used a strong cache * validator (see section 13.3.3), the response SHOULD NOT include * other entity-headers." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5 */ private void cacheGenerated304ForValidatorShouldNotContainEntityHeader( final String headerName, final String headerValue, final String validatorHeader, final String validator, final String conditionalHeader) throws Exception, IOException { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader(validatorHeader, validator); resp1.setHeader(headerName, headerValue); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader(conditionalHeader, validator); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (HttpStatus.SC_NOT_MODIFIED == result.getStatusLine().getStatusCode()) { assertNull(result.getFirstHeader(headerName)); } } private void cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader( final String headerName, final String headerValue) throws Exception, IOException { cacheGenerated304ForValidatorShouldNotContainEntityHeader(headerName, headerValue, "ETag", "\"etag\"", "If-None-Match"); } private void cacheGenerated304ForStrongDateValidatorShouldNotContainEntityHeader( final String headerName, final String headerValue) throws Exception, IOException { cacheGenerated304ForValidatorShouldNotContainEntityHeader(headerName, headerValue, "Last-Modified", DateUtils.formatDate(twoMinutesAgo), "If-Modified-Since"); } @Test public void cacheGenerated304ForStrongEtagValidatorShouldNotContainAllow() throws Exception { cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader( "Allow", "GET,HEAD"); } @Test public void cacheGenerated304ForStrongDateValidatorShouldNotContainAllow() throws Exception { cacheGenerated304ForStrongDateValidatorShouldNotContainEntityHeader( "Allow", "GET,HEAD"); } @Test public void cacheGenerated304ForStrongEtagValidatorShouldNotContainContentEncoding() throws Exception { cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader( "Content-Encoding", "gzip"); } @Test public void cacheGenerated304ForStrongDateValidatorShouldNotContainContentEncoding() throws Exception { cacheGenerated304ForStrongDateValidatorShouldNotContainEntityHeader( "Content-Encoding", "gzip"); } @Test public void cacheGenerated304ForStrongEtagValidatorShouldNotContainContentLanguage() throws Exception { cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader( "Content-Language", "en"); } @Test public void cacheGenerated304ForStrongDateValidatorShouldNotContainContentLanguage() throws Exception { cacheGenerated304ForStrongDateValidatorShouldNotContainEntityHeader( "Content-Language", "en"); } @Test public void cacheGenerated304ForStrongValidatorShouldNotContainContentLength() throws Exception { cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader( "Content-Length", "128"); } @Test public void cacheGenerated304ForStrongDateValidatorShouldNotContainContentLength() throws Exception { cacheGenerated304ForStrongDateValidatorShouldNotContainEntityHeader( "Content-Length", "128"); } @Test public void cacheGenerated304ForStrongValidatorShouldNotContainContentMD5() throws Exception { cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader( "Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ=="); } @Test public void cacheGenerated304ForStrongDateValidatorShouldNotContainContentMD5() throws Exception { cacheGenerated304ForStrongDateValidatorShouldNotContainEntityHeader( "Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ=="); } private void cacheGenerated304ForStrongValidatorShouldNotContainContentRange( final String validatorHeader, final String validator, final String conditionalHeader) throws Exception, IOException, ClientProtocolException { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req1.setHeader("Range","bytes=0-127"); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader(validatorHeader, validator); resp1.setHeader("Content-Range", "bytes 0-127/256"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("If-Range", validator); req2.setHeader("Range","bytes=0-127"); req2.setHeader(conditionalHeader, validator); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader(validatorHeader, validator); // cache module does not currently deal with byte ranges, but we want // this test to work even if it does some day final Capture cap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)).times(0,1); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (!cap.hasCaptured() && HttpStatus.SC_NOT_MODIFIED == result.getStatusLine().getStatusCode()) { // cache generated a 304 assertNull(result.getFirstHeader("Content-Range")); } } @Test public void cacheGenerated304ForStrongEtagValidatorShouldNotContainContentRange() throws Exception { cacheGenerated304ForStrongValidatorShouldNotContainContentRange( "ETag", "\"etag\"", "If-None-Match"); } @Test public void cacheGenerated304ForStrongDateValidatorShouldNotContainContentRange() throws Exception { cacheGenerated304ForStrongValidatorShouldNotContainContentRange( "Last-Modified", DateUtils.formatDate(twoMinutesAgo), "If-Modified-Since"); } @Test public void cacheGenerated304ForStrongEtagValidatorShouldNotContainContentType() throws Exception { cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader( "Content-Type", "text/html"); } @Test public void cacheGenerated304ForStrongDateValidatorShouldNotContainContentType() throws Exception { cacheGenerated304ForStrongDateValidatorShouldNotContainEntityHeader( "Content-Type", "text/html"); } @Test public void cacheGenerated304ForStrongEtagValidatorShouldNotContainLastModified() throws Exception { cacheGenerated304ForStrongETagValidatorShouldNotContainEntityHeader( "Last-Modified", DateUtils.formatDate(tenSecondsAgo)); } @Test public void cacheGenerated304ForStrongDateValidatorShouldNotContainLastModified() throws Exception { cacheGenerated304ForStrongDateValidatorShouldNotContainEntityHeader( "Last-Modified", DateUtils.formatDate(twoMinutesAgo)); } private void shouldStripEntityHeaderFromOrigin304ResponseToStrongValidation( final String entityHeader, final String entityHeaderValue) throws Exception, IOException { final HttpRequestWrapper req = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req.setHeader("If-None-Match", "\"etag\""); final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp.setHeader("Date", DateUtils.formatDate(now)); resp.setHeader("Etag", "\"etag\""); resp.setHeader(entityHeader, entityHeaderValue); backendExpectsAnyRequestAndReturn(resp); replayMocks(); final HttpResponse result = impl.execute(route, req, context, null); verifyMocks(); assertNull(result.getFirstHeader(entityHeader)); } @Test public void shouldStripAllowFromOrigin304ResponseToStrongValidation() throws Exception { shouldStripEntityHeaderFromOrigin304ResponseToStrongValidation( "Allow", "GET,HEAD"); } @Test public void shouldStripContentEncodingFromOrigin304ResponseToStrongValidation() throws Exception { shouldStripEntityHeaderFromOrigin304ResponseToStrongValidation( "Content-Encoding", "gzip"); } @Test public void shouldStripContentLanguageFromOrigin304ResponseToStrongValidation() throws Exception { shouldStripEntityHeaderFromOrigin304ResponseToStrongValidation( "Content-Language", "en"); } @Test public void shouldStripContentLengthFromOrigin304ResponseToStrongValidation() throws Exception { shouldStripEntityHeaderFromOrigin304ResponseToStrongValidation( "Content-Length", "128"); } @Test public void shouldStripContentMD5FromOrigin304ResponseToStrongValidation() throws Exception { shouldStripEntityHeaderFromOrigin304ResponseToStrongValidation( "Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ=="); } @Test public void shouldStripContentTypeFromOrigin304ResponseToStrongValidation() throws Exception { shouldStripEntityHeaderFromOrigin304ResponseToStrongValidation( "Content-Type", "text/html;charset=utf-8"); } @Test public void shouldStripContentRangeFromOrigin304ResponseToStringValidation() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req.setHeader("If-Range","\"etag\""); req.setHeader("Range","bytes=0-127"); final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp.setHeader("Date", DateUtils.formatDate(now)); resp.setHeader("ETag", "\"etag\""); resp.setHeader("Content-Range", "bytes 0-127/256"); backendExpectsAnyRequestAndReturn(resp); replayMocks(); final HttpResponse result = impl.execute(route, req, context, null); verifyMocks(); assertNull(result.getFirstHeader("Content-Range")); } @Test public void shouldStripLastModifiedFromOrigin304ResponseToStrongValidation() throws Exception { shouldStripEntityHeaderFromOrigin304ResponseToStrongValidation( "Last-Modified", DateUtils.formatDate(twoMinutesAgo)); } /* * "For this reason, a cache SHOULD NOT return a stale response if the * client explicitly requests a first-hand or fresh one, unless it is * impossible to comply for technical or policy reasons." */ private HttpRequestWrapper requestToPopulateStaleCacheEntry() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control","public,max-age=5"); resp1.setHeader("Etag","\"etag\""); backendExpectsAnyRequestAndReturn(resp1); return req1; } private void testDoesNotReturnStaleResponseOnError(final HttpRequestWrapper req2) throws Exception, IOException { final HttpRequestWrapper req1 = requestToPopulateStaleCacheEntry(); backendExpectsAnyRequest().andThrow(new IOException()); replayMocks(); impl.execute(route, req1, context, null); HttpResponse result = null; try { result = impl.execute(route, req2, context, null); } catch (final IOException acceptable) { } verifyMocks(); if (result != null) { assertFalse(result.getStatusLine().getStatusCode() == HttpStatus.SC_OK); } } @Test public void testDoesNotReturnStaleResponseIfClientExplicitlyRequestsFirstHandOneWithCacheControl() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req.setHeader("Cache-Control","no-cache"); testDoesNotReturnStaleResponseOnError(req); } @Test public void testDoesNotReturnStaleResponseIfClientExplicitlyRequestsFirstHandOneWithPragma() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req.setHeader("Pragma","no-cache"); testDoesNotReturnStaleResponseOnError(req); } @Test public void testDoesNotReturnStaleResponseIfClientExplicitlyRequestsFreshWithMaxAge() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req.setHeader("Cache-Control","max-age=0"); testDoesNotReturnStaleResponseOnError(req); } @Test public void testDoesNotReturnStaleResponseIfClientExplicitlySpecifiesLargerMaxAge() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req.setHeader("Cache-Control","max-age=20"); testDoesNotReturnStaleResponseOnError(req); } @Test public void testDoesNotReturnStaleResponseIfClientExplicitlyRequestsFreshWithMinFresh() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req.setHeader("Cache-Control","min-fresh=2"); testDoesNotReturnStaleResponseOnError(req); } @Test public void testDoesNotReturnStaleResponseIfClientExplicitlyRequestsFreshWithMaxStale() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req.setHeader("Cache-Control","max-stale=2"); testDoesNotReturnStaleResponseOnError(req); } @Test public void testMayReturnStaleResponseIfClientExplicitlySpecifiesAcceptableMaxStale() throws Exception { final HttpRequestWrapper req1 = requestToPopulateStaleCacheEntry(); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Cache-Control","max-stale=20"); backendExpectsAnyRequest().andThrow(new IOException()).times(0,1); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode()); assertNotNull(result.getFirstHeader("Warning")); } /* * "A correct cache MUST respond to a request with the most up-to-date * response held by the cache that is appropriate to the request * (see sections 13.2.5, 13.2.6, and 13.12) which meets one of the * following conditions: * * 1. It has been checked for equivalence with what the origin server * would have returned by revalidating the response with the * origin server (section 13.3); * * 2. It is "fresh enough" (see section 13.2). In the default case, * this means it meets the least restrictive freshness requirement * of the client, origin server, and cache (see section 14.9); if * the origin server so specifies, it is the freshness requirement * of the origin server alone. * * If a stored response is not "fresh enough" by the most * restrictive freshness requirement of both the client and the * origin server, in carefully considered circumstances the cache * MAY still return the response with the appropriate Warning * header (see section 13.1.5 and 14.46), unless such a response * is prohibited (e.g., by a "no-store" cache-directive, or by a * "no-cache" cache-request-directive; see section 14.9). * * 3. It is an appropriate 304 (Not Modified), 305 (Proxy Redirect), * or error (4xx or 5xx) response message. * * If the cache can not communicate with the origin server, then a * correct cache SHOULD respond as above if the response can be * correctly served from the cache..." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.1.1 */ @Test public void testReturnsCachedResponsesAppropriatelyWhenNoOriginCommunication() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); resp1.setHeader("Cache-Control", "public, max-age=5"); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); backendExpectsAnyRequest().andThrow(new IOException()).anyTimes(); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode()); boolean warning111Found = false; for(final Header h : result.getHeaders("Warning")) { for(final WarningValue wv : WarningValue.getWarningValues(h)) { if (wv.getWarnCode() == 111) { warning111Found = true; break; } } } assertTrue(warning111Found); } /* * "If a cache receives a response (either an entire response, or a * 304 (Not Modified) response) that it would normally forward to the * requesting client, and the received response is no longer fresh, * the cache SHOULD forward it to the requesting client without adding * a new Warning (but without removing any existing Warning headers). * A cache SHOULD NOT attempt to revalidate a response simply because * that response became stale in transit; this might lead to an * infinite loop." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.1.1 */ @Test public void testDoesNotAddNewWarningHeaderIfResponseArrivesStale() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); originResponse.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); originResponse.setHeader("Cache-Control","public, max-age=5"); originResponse.setHeader("ETag","\"etag\""); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); assertNull(result.getFirstHeader("Warning")); } @Test public void testForwardsExistingWarningHeadersOnResponseThatArrivesStale() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); originResponse.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); originResponse.setHeader("Cache-Control","public, max-age=5"); originResponse.setHeader("ETag","\"etag\""); originResponse.addHeader("Age","10"); final String warning = "110 fred \"Response is stale\""; originResponse.addHeader("Warning",warning); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); assertEquals(warning, result.getFirstHeader("Warning").getValue()); } /* * "A transparent proxy SHOULD NOT modify an end-to-end header unless * the definition of that header requires or specifically allows that." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.2 */ private void testDoesNotModifyHeaderOnResponses(final String headerName) throws Exception { final String headerValue = HttpTestUtils .getCanonicalHeaderValue(originResponse, headerName); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); assertEquals(headerValue, result.getFirstHeader(headerName).getValue()); } private void testDoesNotModifyHeaderOnRequests(final String headerName) throws Exception { final String headerValue = HttpTestUtils.getCanonicalHeaderValue(request, headerName); final Capture cap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); assertEquals(headerValue, HttpTestUtils.getCanonicalHeaderValue(cap.getValue(), headerName)); } @Test public void testDoesNotModifyAcceptRangesOnResponses() throws Exception { final String headerName = "Accept-Ranges"; originResponse.setHeader(headerName,"bytes"); testDoesNotModifyHeaderOnResponses(headerName); } @Test public void testDoesNotModifyAuthorizationOnRequests() throws Exception { request.setHeader("Authorization", "Basic dXNlcjpwYXNzd2Q="); testDoesNotModifyHeaderOnRequests("Authorization"); } @Test public void testDoesNotModifyContentLengthOnRequests() throws Exception { final HttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/", HttpVersion.HTTP_1_1); post.setEntity(HttpTestUtils.makeBody(128)); post.setHeader("Content-Length","128"); request = HttpRequestWrapper.wrap(post); testDoesNotModifyHeaderOnRequests("Content-Length"); } @Test public void testDoesNotModifyContentLengthOnResponses() throws Exception { originResponse.setEntity(HttpTestUtils.makeBody(128)); originResponse.setHeader("Content-Length","128"); testDoesNotModifyHeaderOnResponses("Content-Length"); } @Test public void testDoesNotModifyContentMD5OnRequests() throws Exception { final HttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/", HttpVersion.HTTP_1_1); post.setEntity(HttpTestUtils.makeBody(128)); post.setHeader("Content-Length","128"); post.setHeader("Content-MD5","Q2hlY2sgSW50ZWdyaXR5IQ=="); request = HttpRequestWrapper.wrap(post); testDoesNotModifyHeaderOnRequests("Content-MD5"); } @Test public void testDoesNotModifyContentMD5OnResponses() throws Exception { originResponse.setEntity(HttpTestUtils.makeBody(128)); originResponse.setHeader("Content-MD5","Q2hlY2sgSW50ZWdyaXR5IQ=="); testDoesNotModifyHeaderOnResponses("Content-MD5"); } @Test public void testDoesNotModifyContentRangeOnRequests() throws Exception { final HttpEntityEnclosingRequest put = new BasicHttpEntityEnclosingRequest("PUT", "/", HttpVersion.HTTP_1_1); put.setEntity(HttpTestUtils.makeBody(128)); put.setHeader("Content-Length","128"); put.setHeader("Content-Range","bytes 0-127/256"); request = HttpRequestWrapper.wrap(put); testDoesNotModifyHeaderOnRequests("Content-Range"); } @Test public void testDoesNotModifyContentRangeOnResponses() throws Exception { request.setHeader("Range","bytes=0-128"); originResponse.setStatusCode(HttpStatus.SC_PARTIAL_CONTENT); originResponse.setReasonPhrase("Partial Content"); originResponse.setEntity(HttpTestUtils.makeBody(128)); originResponse.setHeader("Content-Range","bytes 0-127/256"); testDoesNotModifyHeaderOnResponses("Content-Range"); } @Test public void testDoesNotModifyContentTypeOnRequests() throws Exception { final HttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/", HttpVersion.HTTP_1_1); post.setEntity(HttpTestUtils.makeBody(128)); post.setHeader("Content-Length","128"); post.setHeader("Content-Type","application/octet-stream"); request = HttpRequestWrapper.wrap(post); testDoesNotModifyHeaderOnRequests("Content-Type"); } @Test public void testDoesNotModifyContentTypeOnResponses() throws Exception { originResponse.setHeader("Content-Type","application/octet-stream"); testDoesNotModifyHeaderOnResponses("Content-Type"); } @Test public void testDoesNotModifyDateOnRequests() throws Exception { request.setHeader("Date", DateUtils.formatDate(new Date())); testDoesNotModifyHeaderOnRequests("Date"); } @Test public void testDoesNotModifyDateOnResponses() throws Exception { originResponse.setHeader("Date", DateUtils.formatDate(new Date())); testDoesNotModifyHeaderOnResponses("Date"); } @Test public void testDoesNotModifyETagOnResponses() throws Exception { originResponse.setHeader("ETag", "\"random-etag\""); testDoesNotModifyHeaderOnResponses("ETag"); } @Test public void testDoesNotModifyExpiresOnResponses() throws Exception { originResponse.setHeader("Expires", DateUtils.formatDate(new Date())); testDoesNotModifyHeaderOnResponses("Expires"); } @Test public void testDoesNotModifyFromOnRequests() throws Exception { request.setHeader("From", "foo@example.com"); testDoesNotModifyHeaderOnRequests("From"); } @Test public void testDoesNotModifyIfMatchOnRequests() throws Exception { request = HttpRequestWrapper.wrap(HttpRequestWrapper.wrap( new BasicHttpRequest("DELETE", "/", HttpVersion.HTTP_1_1))); request.setHeader("If-Match", "\"etag\""); testDoesNotModifyHeaderOnRequests("If-Match"); } @Test public void testDoesNotModifyIfModifiedSinceOnRequests() throws Exception { request.setHeader("If-Modified-Since", DateUtils.formatDate(new Date())); testDoesNotModifyHeaderOnRequests("If-Modified-Since"); } @Test public void testDoesNotModifyIfNoneMatchOnRequests() throws Exception { request.setHeader("If-None-Match", "\"etag\""); testDoesNotModifyHeaderOnRequests("If-None-Match"); } @Test public void testDoesNotModifyIfRangeOnRequests() throws Exception { request.setHeader("Range","bytes=0-128"); request.setHeader("If-Range", "\"etag\""); testDoesNotModifyHeaderOnRequests("If-Range"); } @Test public void testDoesNotModifyIfUnmodifiedSinceOnRequests() throws Exception { request = HttpRequestWrapper.wrap(HttpRequestWrapper.wrap( new BasicHttpRequest("DELETE", "/", HttpVersion.HTTP_1_1))); request.setHeader("If-Unmodified-Since", DateUtils.formatDate(new Date())); testDoesNotModifyHeaderOnRequests("If-Unmodified-Since"); } @Test public void testDoesNotModifyLastModifiedOnResponses() throws Exception { originResponse.setHeader("Last-Modified", DateUtils.formatDate(new Date())); testDoesNotModifyHeaderOnResponses("Last-Modified"); } @Test public void testDoesNotModifyLocationOnResponses() throws Exception { originResponse.setStatusCode(HttpStatus.SC_TEMPORARY_REDIRECT); originResponse.setReasonPhrase("Temporary Redirect"); originResponse.setHeader("Location", "http://foo.example.com/bar"); testDoesNotModifyHeaderOnResponses("Location"); } @Test public void testDoesNotModifyRangeOnRequests() throws Exception { request.setHeader("Range", "bytes=0-128"); testDoesNotModifyHeaderOnRequests("Range"); } @Test public void testDoesNotModifyRefererOnRequests() throws Exception { request.setHeader("Referer", "http://foo.example.com/bar"); testDoesNotModifyHeaderOnRequests("Referer"); } @Test public void testDoesNotModifyRetryAfterOnResponses() throws Exception { originResponse.setStatusCode(HttpStatus.SC_SERVICE_UNAVAILABLE); originResponse.setReasonPhrase("Service Unavailable"); originResponse.setHeader("Retry-After", "120"); testDoesNotModifyHeaderOnResponses("Retry-After"); } @Test public void testDoesNotModifyServerOnResponses() throws Exception { originResponse.setHeader("Server", "SomeServer/1.0"); testDoesNotModifyHeaderOnResponses("Server"); } @Test public void testDoesNotModifyUserAgentOnRequests() throws Exception { request.setHeader("User-Agent", "MyClient/1.0"); testDoesNotModifyHeaderOnRequests("User-Agent"); } @Test public void testDoesNotModifyVaryOnResponses() throws Exception { request.setHeader("Accept-Encoding","identity"); originResponse.setHeader("Vary", "Accept-Encoding"); testDoesNotModifyHeaderOnResponses("Vary"); } @Test public void testDoesNotModifyExtensionHeaderOnRequests() throws Exception { request.setHeader("X-Extension","x-value"); testDoesNotModifyHeaderOnRequests("X-Extension"); } @Test public void testDoesNotModifyExtensionHeaderOnResponses() throws Exception { originResponse.setHeader("X-Extension", "x-value"); testDoesNotModifyHeaderOnResponses("X-Extension"); } /* * "[HTTP/1.1 clients], If only a Last-Modified value has been provided * by the origin server, SHOULD use that value in non-subrange cache- * conditional requests (using If-Modified-Since)." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.4 */ @Test public void testUsesLastModifiedDateForCacheConditionalRequests() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Date twentySecondsAgo = new Date(now.getTime() - 20 * 1000L); final String lmDate = DateUtils.formatDate(twentySecondsAgo); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Last-Modified", lmDate); resp1.setHeader("Cache-Control","max-age=5"); backendExpectsAnyRequestAndReturn(resp1); final Capture cap = new Capture(); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = HttpTestUtils.make200Response(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); final HttpRequest captured = cap.getValue(); final Header ifModifiedSince = captured.getFirstHeader("If-Modified-Since"); assertEquals(lmDate, ifModifiedSince.getValue()); } /* * "[HTTP/1.1 clients], if both an entity tag and a Last-Modified value * have been provided by the origin server, SHOULD use both validators * in cache-conditional requests. This allows both HTTP/1.0 and * HTTP/1.1 caches to respond appropriately." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.4 */ @Test public void testUsesBothLastModifiedAndETagForConditionalRequestsIfAvailable() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Date twentySecondsAgo = new Date(now.getTime() - 20 * 1000L); final String lmDate = DateUtils.formatDate(twentySecondsAgo); final String etag = "\"etag\""; final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Last-Modified", lmDate); resp1.setHeader("Cache-Control","max-age=5"); resp1.setHeader("ETag", etag); backendExpectsAnyRequestAndReturn(resp1); final Capture cap = new Capture(); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = HttpTestUtils.make200Response(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); final HttpRequest captured = cap.getValue(); final Header ifModifiedSince = captured.getFirstHeader("If-Modified-Since"); assertEquals(lmDate, ifModifiedSince.getValue()); final Header ifNoneMatch = captured.getFirstHeader("If-None-Match"); assertEquals(etag, ifNoneMatch.getValue()); } /* * "If an origin server wishes to force a semantically transparent cache * to validate every request, it MAY assign an explicit expiration time * in the past. This means that the response is always stale, and so the * cache SHOULD validate it before using it for subsequent requests." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.1 */ @Test public void testRevalidatesCachedResponseWithExpirationInThePast() throws Exception { final Date now = new Date(); final Date oneSecondAgo = new Date(now.getTime() - 1 * 1000L); final Date oneSecondFromNow = new Date(now.getTime() + 1 * 1000L); final Date twoSecondsFromNow = new Date(now.getTime() + 2 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Expires",DateUtils.formatDate(oneSecondAgo)); resp1.setHeader("Cache-Control", "public"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpRequestWrapper revalidate = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/",HttpVersion.HTTP_1_1)); revalidate.setHeader("If-None-Match","\"etag\""); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp2.setHeader("Date", DateUtils.formatDate(twoSecondsFromNow)); resp2.setHeader("Expires", DateUtils.formatDate(oneSecondFromNow)); resp2.setHeader("ETag","\"etag\""); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), eqRequest(revalidate), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode()); } /* "When a client tries to revalidate a cache entry, and the response * it receives contains a Date header that appears to be older than the * one for the existing entry, then the client SHOULD repeat the * request unconditionally, and include * Cache-Control: max-age=0 * to force any intermediate caches to validate their copies directly * with the origin server, or * Cache-Control: no-cache * to force any intermediate caches to obtain a new copy from the * origin server." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.6 */ @Test public void testRetriesValidationThatResultsInAnOlderDated304Response() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Date elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control","max-age=5"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp2.setHeader("ETag","\"etag\""); resp2.setHeader("Date", DateUtils.formatDate(elevenSecondsAgo)); backendExpectsAnyRequestAndReturn(resp2); final Capture cap = new Capture(); final HttpResponse resp3 = HttpTestUtils.make200Response(); resp3.setHeader("ETag","\"etag2\""); resp3.setHeader("Date", DateUtils.formatDate(now)); resp3.setHeader("Cache-Control","max-age=5"); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp3)); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); final HttpRequest captured = cap.getValue(); boolean hasMaxAge0 = false; boolean hasNoCache = false; for(final Header h : captured.getHeaders("Cache-Control")) { for(final HeaderElement elt : h.getElements()) { if ("max-age".equals(elt.getName())) { try { final int maxage = Integer.parseInt(elt.getValue()); if (maxage == 0) { hasMaxAge0 = true; } } catch (final NumberFormatException nfe) { // nop } } else if ("no-cache".equals(elt.getName())) { hasNoCache = true; } } } assertTrue(hasMaxAge0 || hasNoCache); assertNull(captured.getFirstHeader("If-None-Match")); assertNull(captured.getFirstHeader("If-Modified-Since")); assertNull(captured.getFirstHeader("If-Range")); assertNull(captured.getFirstHeader("If-Match")); assertNull(captured.getFirstHeader("If-Unmodified-Since")); } /* "If an entity tag was assigned to a cached representation, the * forwarded request SHOULD be conditional and include the entity * tags in an If-None-Match header field from all its cache entries * for the resource." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6 */ @Test public void testSendsAllVariantEtagsInConditionalRequest() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1)); req1.setHeader("User-Agent","agent1"); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Vary","User-Agent"); resp1.setHeader("Etag","\"etag1\""); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1)); req2.setHeader("User-Agent","agent2"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Vary","User-Agent"); resp2.setHeader("Etag","\"etag2\""); backendExpectsAnyRequestAndReturn(resp2); final Capture cap = new Capture(); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET","/",HttpVersion.HTTP_1_1)); req3.setHeader("User-Agent","agent3"); final HttpResponse resp3 = HttpTestUtils.make200Response(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp3)); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); impl.execute(route, req3, context, null); verifyMocks(); final HttpRequest captured = cap.getValue(); boolean foundEtag1 = false; boolean foundEtag2 = false; for(final Header h : captured.getHeaders("If-None-Match")) { for(final String etag : h.getValue().split(",")) { if ("\"etag1\"".equals(etag.trim())) { foundEtag1 = true; } if ("\"etag2\"".equals(etag.trim())) { foundEtag2 = true; } } } assertTrue(foundEtag1 && foundEtag2); } /* "If the entity-tag of the new response matches that of an existing * entry, the new response SHOULD be used to update the header fields * of the existing entry, and the result MUST be returned to the * client." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6 */ @Test public void testResponseToExistingVariantsUpdatesEntry() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("User-Agent", "agent1"); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Vary", "User-Agent"); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("ETag", "\"etag1\""); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("User-Agent", "agent2"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp2.setHeader("Vary", "User-Agent"); resp2.setHeader("Cache-Control", "max-age=3600"); resp2.setHeader("ETag", "\"etag2\""); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req3.setHeader("User-Agent", "agent3"); final HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp3.setHeader("Date", DateUtils.formatDate(now)); resp3.setHeader("ETag", "\"etag1\""); backendExpectsAnyRequestAndReturn(resp3); final HttpRequestWrapper req4 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req4.setHeader("User-Agent", "agent1"); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); final HttpResponse result1 = impl.execute(route, req3, context, null); final HttpResponse result2 = impl.execute(route, req4, context, null); verifyMocks(); assertEquals(HttpStatus.SC_OK, result1.getStatusLine().getStatusCode()); assertEquals("\"etag1\"", result1.getFirstHeader("ETag").getValue()); assertEquals(DateUtils.formatDate(now), result1.getFirstHeader("Date").getValue()); assertEquals(DateUtils.formatDate(now), result2.getFirstHeader("Date").getValue()); } @Test public void testResponseToExistingVariantsIsCachedForFutureResponses() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("User-Agent", "agent1"); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Vary", "User-Agent"); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("ETag", "\"etag1\""); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("User-Agent", "agent2"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader("ETag", "\"etag1\""); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req3.setHeader("User-Agent", "agent2"); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); impl.execute(route, req3, context, null); verifyMocks(); } /* "If any of the existing cache entries contains only partial content * for the associated entity, its entity-tag SHOULD NOT be included in * the If-None-Match header field unless the request is for a range * that would be fully satisfied by that entry." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6 */ @Test public void variantNegotiationsDoNotIncludeEtagsForPartialResponses() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req1.setHeader("User-Agent", "agent1"); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("Vary", "User-Agent"); resp1.setHeader("ETag", "\"etag1\""); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("User-Agent", "agent2"); req2.setHeader("Range", "bytes=0-49"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp2.setEntity(HttpTestUtils.makeBody(50)); resp2.setHeader("Content-Length","50"); resp2.setHeader("Content-Range","bytes 0-49/100"); resp2.setHeader("Vary","User-Agent"); resp2.setHeader("ETag", "\"etag2\""); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Date", DateUtils.formatDate(new Date())); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req3.setHeader("User-Agent", "agent3"); final HttpResponse resp3 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("Vary", "User-Agent"); resp1.setHeader("ETag", "\"etag3\""); final Capture cap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp3)); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); impl.execute(route, req3, context, null); verifyMocks(); final HttpRequest captured = cap.getValue(); for(final Header h : captured.getHeaders("If-None-Match")) { for(final HeaderElement elt : h.getElements()) { assertFalse("\"etag2\"".equals(elt.toString())); } } } /* "If a cache receives a successful response whose Content-Location * field matches that of an existing cache entry for the same Request- * URI, whose entity-tag differs from that of the existing entry, and * whose Date is more recent than that of the existing entry, the * existing entry SHOULD NOT be returned in response to future requests * and SHOULD be deleted from the cache. * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6 */ @Test public void cachedEntryShouldNotBeUsedIfMoreRecentMentionInContentLocation() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new HttpGet("http://foo.example.com/")); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("ETag", "\"old-etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new HttpPost("http://foo.example.com/bar")); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag", "\"new-etag\""); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader("Content-Location", "http://foo.example.com/"); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new HttpGet("http://foo.example.com")); final HttpResponse resp3 = HttpTestUtils.make200Response(); backendExpectsAnyRequestAndReturn(resp3); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); impl.execute(route, req3, context, null); verifyMocks(); } /* * "This specifically means that responses from HTTP/1.0 servers for such * URIs [those containing a '?' in the rel_path part] SHOULD NOT be taken * from a cache." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.9 */ @Test public void responseToGetWithQueryFrom1_0OriginAndNoExpiresIsNotCached() throws Exception { final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new HttpGet("http://foo.example.com/bar?baz=quux")); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK"); resp2.setEntity(HttpTestUtils.makeBody(200)); resp2.setHeader("Content-Length","200"); resp2.setHeader("Date", DateUtils.formatDate(now)); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req2, context, null); verifyMocks(); } @Test public void responseToGetWithQueryFrom1_0OriginVia1_1ProxyAndNoExpiresIsNotCached() throws Exception { final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new HttpGet("http://foo.example.com/bar?baz=quux")); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK"); resp2.setEntity(HttpTestUtils.makeBody(200)); resp2.setHeader("Content-Length","200"); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader("Via","1.0 someproxy"); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req2, context, null); verifyMocks(); } /* * "A cache that passes through requests for methods it does not * understand SHOULD invalidate any entities referred to by the * Request-URI." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.10 */ @Test public void shouldInvalidateNonvariantCacheEntryForUnknownMethod() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("FROB", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Cache-Control","max-age=3600"); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp3 = HttpTestUtils.make200Response(); resp3.setHeader("ETag", "\"etag\""); backendExpectsAnyRequestAndReturn(resp3); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); final HttpResponse result = impl.execute(route, req3, context, null); verifyMocks(); assertTrue(HttpTestUtils.semanticallyTransparent(resp3, result)); } @Test public void shouldInvalidateAllVariantsForUnknownMethod() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("User-Agent", "agent1"); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Vary", "User-Agent"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("User-Agent", "agent2"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Vary", "User-Agent"); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("FROB", "/", HttpVersion.HTTP_1_1)); req3.setHeader("User-Agent", "agent3"); final HttpResponse resp3 = HttpTestUtils.make200Response(); resp3.setHeader("Cache-Control","max-age=3600"); backendExpectsAnyRequestAndReturn(resp3); final HttpRequestWrapper req4 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req4.setHeader("User-Agent", "agent1"); final HttpResponse resp4 = HttpTestUtils.make200Response(); resp4.setHeader("ETag", "\"etag1\""); backendExpectsAnyRequestAndReturn(resp4); final HttpRequestWrapper req5 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req5.setHeader("User-Agent", "agent2"); final HttpResponse resp5 = HttpTestUtils.make200Response(); resp5.setHeader("ETag", "\"etag2\""); backendExpectsAnyRequestAndReturn(resp5); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); impl.execute(route, req3, context, null); final HttpResponse result4 = impl.execute(route, req4, context, null); final HttpResponse result5 = impl.execute(route, req5, context, null); verifyMocks(); assertTrue(HttpTestUtils.semanticallyTransparent(resp4, result4)); assertTrue(HttpTestUtils.semanticallyTransparent(resp5, result5)); } /* * "If a new cacheable response is received from a resource while any * existing responses for the same resource are cached, the cache * SHOULD use the new response to reply to the current request." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.12 */ @Test public void cacheShouldUpdateWithNewCacheableResponse() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("ETag", "\"etag1\""); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("Cache-Control", "max-age=0"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader("Cache-Control", "max-age=3600"); resp2.setHeader("ETag", "\"etag2\""); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); final HttpResponse result = impl.execute(route, req3, context, null); verifyMocks(); assertTrue(HttpTestUtils.semanticallyTransparent(resp2, result)); } /* * "Many HTTP/1.0 cache implementations will treat an Expires value * that is less than or equal to the response Date value as being * equivalent to the Cache-Control response directive 'no-cache'. * If an HTTP/1.1 cache receives such a response, and the response * does not include a Cache-Control header field, it SHOULD consider * the response to be non-cacheable in order to retain compatibility * with HTTP/1.0 servers." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3 */ @Test public void expiresEqualToDateWithNoCacheControlIsNotCacheable() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Expires", DateUtils.formatDate(now)); resp1.removeHeaders("Cache-Control"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("Cache-Control", "max-stale=1000"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag", "\"etag2\""); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertTrue(HttpTestUtils.semanticallyTransparent(resp2, result)); } @Test public void expiresPriorToDateWithNoCacheControlIsNotCacheable() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Expires", DateUtils.formatDate(tenSecondsAgo)); resp1.removeHeaders("Cache-Control"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("Cache-Control", "max-stale=1000"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag", "\"etag2\""); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertTrue(HttpTestUtils.semanticallyTransparent(resp2, result)); } /* * "If a request includes the no-cache directive, it SHOULD NOT * include min-fresh, max-stale, or max-age." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 */ @Test public void otherFreshnessRequestDirectivesNotAllowedWithNoCache() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req1.setHeader("Cache-Control", "min-fresh=10, no-cache"); req1.addHeader("Cache-Control", "max-stale=0, max-age=0"); final Capture cap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(HttpTestUtils.make200Response())); replayMocks(); impl.execute(route, req1, context, null); verifyMocks(); final HttpRequest captured = cap.getValue(); boolean foundNoCache = false; boolean foundDisallowedDirective = false; final List disallowed = Arrays.asList("min-fresh", "max-stale", "max-age"); for(final Header h : captured.getHeaders("Cache-Control")) { for(final HeaderElement elt : h.getElements()) { if (disallowed.contains(elt.getName())) { foundDisallowedDirective = true; } if ("no-cache".equals(elt.getName())) { foundNoCache = true; } } } assertTrue(foundNoCache); assertFalse(foundDisallowedDirective); } /* * "To do this, the client may include the only-if-cached directive in * a request. If it receives this directive, a cache SHOULD either * respond using a cached entry that is consistent with the other * constraints of the request, or respond with a 504 (Gateway Timeout) * status." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 */ @Test public void cacheMissResultsIn504WithOnlyIfCached() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req.setHeader("Cache-Control", "only-if-cached"); replayMocks(); final HttpResponse result = impl.execute(route, req, context, null); verifyMocks(); assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT, result.getStatusLine().getStatusCode()); } @Test public void cacheHitOkWithOnlyIfCached() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("Cache-Control", "only-if-cached"); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertTrue(HttpTestUtils.semanticallyTransparent(resp1, result)); } @Test public void returns504ForStaleEntryWithOnlyIfCached() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control","max-age=5"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("Cache-Control", "only-if-cached"); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT, result.getStatusLine().getStatusCode()); } @Test public void returnsStaleCacheEntryWithOnlyIfCachedAndMaxStale() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control","max-age=5"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("Cache-Control", "max-stale=20, only-if-cached"); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertTrue(HttpTestUtils.semanticallyTransparent(resp1, result)); } @Test public void issues304EvenWithWeakETag() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "max-age=300"); resp1.setHeader("ETag","W/\"weak-sauce\""); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("If-None-Match","W/\"weak-sauce\""); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode()); } } ././@LongLink0100644 0000000 0000000 00000000173 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRequirements.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestPro0100644 0000000 0000000 00001026654 12301751715 032333 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import java.io.InputStream; import java.net.SocketTimeoutException; import java.util.Date; import java.util.Random; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.ProtocolVersion; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.DateUtils; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.entity.BasicHttpEntity; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpEntityEnclosingRequest; import org.apache.http.message.BasicHttpRequest; import org.apache.http.message.BasicHttpResponse; import org.apache.http.protocol.HTTP; import org.easymock.Capture; import org.easymock.classextension.EasyMock; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; /** * We are a conditionally-compliant HTTP/1.1 client with a cache. However, a lot * of the rules for proxies apply to us, as far as proper operation of the * requests that pass through us. Generally speaking, we want to make sure that * any response returned from our HttpClient.execute() methods is conditionally * compliant with the rules for an HTTP/1.1 server, and that any requests we * pass downstream to the backend HttpClient are are conditionally compliant * with the rules for an HTTP/1.1 client. */ public class TestProtocolRequirements extends AbstractProtocolTest { @Test public void testCacheMissOnGETUsesOriginResponse() throws Exception { EasyMock.expect( mockBackend.execute( EasyMock.eq(route), eqRequest(request), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertTrue(HttpTestUtils.semanticallyTransparent(originResponse, result)); } /* * "Proxy and gateway applications need to be careful when forwarding * messages in protocol versions different from that of the application. * Since the protocol version indicates the protocol capability of the * sender, a proxy/gateway MUST NOT send a message with a version indicator * which is greater than its actual version. If a higher version request is * received, the proxy/gateway MUST either downgrade the request version, or * respond with an error, or switch to tunnel behavior." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.1 */ @Test public void testHigherMajorProtocolVersionsOnRequestSwitchToTunnelBehavior() throws Exception { // tunnel behavior: I don't muck with request or response in // any way request = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/foo", new ProtocolVersion("HTTP", 2, 13))); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), eqRequest(request), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertSame(originResponse, result); } @Test public void testHigher1_XProtocolVersionsDowngradeTo1_1() throws Exception { request = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/foo", new ProtocolVersion("HTTP", 1, 2))); final HttpRequestWrapper downgraded = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1)); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), eqRequest(downgraded), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertTrue(HttpTestUtils.semanticallyTransparent(originResponse, result)); } /* * "Due to interoperability problems with HTTP/1.0 proxies discovered since * the publication of RFC 2068[33], caching proxies MUST, gateways MAY, and * tunnels MUST NOT upgrade the request to the highest version they support. * The proxy/gateway's response to that request MUST be in the same major * version as the request." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.1 */ @Test public void testRequestsWithLowerProtocolVersionsGetUpgradedTo1_1() throws Exception { request = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/foo", new ProtocolVersion("HTTP", 1, 0))); final HttpRequestWrapper upgraded = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1)); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), eqRequest(upgraded), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertTrue(HttpTestUtils.semanticallyTransparent(originResponse, result)); } /* * "An HTTP server SHOULD send a response version equal to the highest * version for which the server is at least conditionally compliant, and * whose major version is less than or equal to the one received in the * request." * * http://www.ietf.org/rfc/rfc2145.txt */ @Test public void testLowerOriginResponsesUpgradedToOurVersion1_1() throws Exception { originResponse = Proxies.enhanceResponse( new BasicHttpResponse(new ProtocolVersion("HTTP", 1, 2), HttpStatus.SC_OK, "OK")); originResponse.setHeader("Date", DateUtils.formatDate(new Date())); originResponse.setHeader("Server", "MockOrigin/1.0"); originResponse.setEntity(body); // not testing this internal behavior in this test, just want // to check the protocol version that comes out the other end EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertEquals(HttpVersion.HTTP_1_1, result.getProtocolVersion()); } @Test public void testResponseToA1_0RequestShouldUse1_1() throws Exception { request = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/foo", new ProtocolVersion("HTTP", 1, 0))); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertEquals(HttpVersion.HTTP_1_1, result.getProtocolVersion()); } /* * "A proxy MUST forward an unknown header, unless it is protected by a * Connection header." http://www.ietf.org/rfc/rfc2145.txt */ @Test public void testForwardsUnknownHeadersOnRequestsFromHigherProtocolVersions() throws Exception { request = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/foo", new ProtocolVersion("HTTP", 1, 2))); request.removeHeaders("Connection"); request.addHeader("X-Unknown-Header", "some-value"); final HttpRequestWrapper downgraded = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1)); downgraded.removeHeaders("Connection"); downgraded.addHeader("X-Unknown-Header", "some-value"); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), eqRequest(downgraded), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); } /* * "A server MUST NOT send transfer-codings to an HTTP/1.0 client." * http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6 */ @Test public void testTransferCodingsAreNotSentToAnHTTP_1_0Client() throws Exception { originResponse.setHeader("Transfer-Encoding", "identity"); request = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/foo", new ProtocolVersion("HTTP", 1, 0))); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertNull(result.getFirstHeader("TE")); Assert.assertNull(result.getFirstHeader("Transfer-Encoding")); } /* * "Multiple message-header fields with the same field-name MAY be present * in a message if and only if the entire field-value for that header field * is defined as a comma-separated list [i.e., #(values)]. It MUST be * possible to combine the multiple header fields into one * "field-name: field-value" pair, without changing the semantics of the * message, by appending each subsequent field-value to the first, each * separated by a comma. The order in which header fields with the same * field-name are received is therefore significant to the interpretation of * the combined field value, and thus a proxy MUST NOT change the order of * these field values when a message is forwarded." * http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 */ private void testOrderOfMultipleHeadersIsPreservedOnRequests(final String h, final HttpRequestWrapper request) throws Exception { final Capture reqCapture = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.capture(reqCapture), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); final HttpRequest forwarded = reqCapture.getValue(); Assert.assertNotNull(forwarded); final String expected = HttpTestUtils.getCanonicalHeaderValue(request, h); final String actual = HttpTestUtils.getCanonicalHeaderValue(forwarded, h); if (!actual.contains(expected)) { Assert.assertEquals(expected, actual); } } @Test public void testOrderOfMultipleAcceptHeaderValuesIsPreservedOnRequests() throws Exception { request.addHeader("Accept", "audio/*; q=0.2, audio/basic"); request.addHeader("Accept", "text/*, text/html, text/html;level=1, */*"); testOrderOfMultipleHeadersIsPreservedOnRequests("Accept", request); } @Test public void testOrderOfMultipleAcceptCharsetHeadersIsPreservedOnRequests() throws Exception { request.addHeader("Accept-Charset", "iso-8859-5"); request.addHeader("Accept-Charset", "unicode-1-1;q=0.8"); testOrderOfMultipleHeadersIsPreservedOnRequests("Accept-Charset", request); } @Test public void testOrderOfMultipleAcceptEncodingHeadersIsPreservedOnRequests() throws Exception { request.addHeader("Accept-Encoding", "identity"); request.addHeader("Accept-Encoding", "compress, gzip"); testOrderOfMultipleHeadersIsPreservedOnRequests("Accept-Encoding", request); } @Test public void testOrderOfMultipleAcceptLanguageHeadersIsPreservedOnRequests() throws Exception { request.addHeader("Accept-Language", "da, en-gb;q=0.8, en;q=0.7"); request.addHeader("Accept-Language", "i-cherokee"); testOrderOfMultipleHeadersIsPreservedOnRequests("Accept-Encoding", request); } @Test public void testOrderOfMultipleAllowHeadersIsPreservedOnRequests() throws Exception { final BasicHttpEntityEnclosingRequest put = new BasicHttpEntityEnclosingRequest("PUT", "/", HttpVersion.HTTP_1_1); put.setEntity(body); put.addHeader("Allow", "GET, HEAD"); put.addHeader("Allow", "DELETE"); put.addHeader("Content-Length", "128"); testOrderOfMultipleHeadersIsPreservedOnRequests("Allow", HttpRequestWrapper.wrap(put)); } @Test public void testOrderOfMultipleCacheControlHeadersIsPreservedOnRequests() throws Exception { request.addHeader("Cache-Control", "max-age=5"); request.addHeader("Cache-Control", "min-fresh=10"); testOrderOfMultipleHeadersIsPreservedOnRequests("Cache-Control", request); } @Test public void testOrderOfMultipleContentEncodingHeadersIsPreservedOnRequests() throws Exception { final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/", HttpVersion.HTTP_1_1); post.setEntity(body); post.addHeader("Content-Encoding", "gzip"); post.addHeader("Content-Encoding", "compress"); post.addHeader("Content-Length", "128"); testOrderOfMultipleHeadersIsPreservedOnRequests("Content-Encoding", HttpRequestWrapper.wrap(post)); } @Test public void testOrderOfMultipleContentLanguageHeadersIsPreservedOnRequests() throws Exception { final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/", HttpVersion.HTTP_1_1); post.setEntity(body); post.addHeader("Content-Language", "mi"); post.addHeader("Content-Language", "en"); post.addHeader("Content-Length", "128"); testOrderOfMultipleHeadersIsPreservedOnRequests("Content-Language", HttpRequestWrapper.wrap(post)); } @Test public void testOrderOfMultipleExpectHeadersIsPreservedOnRequests() throws Exception { final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/", HttpVersion.HTTP_1_1); post.setEntity(body); post.addHeader("Expect", "100-continue"); post.addHeader("Expect", "x-expect=true"); post.addHeader("Content-Length", "128"); testOrderOfMultipleHeadersIsPreservedOnRequests("Expect", HttpRequestWrapper.wrap(post)); } @Test public void testOrderOfMultiplePragmaHeadersIsPreservedOnRequests() throws Exception { request.addHeader("Pragma", "no-cache"); request.addHeader("Pragma", "x-pragma-1, x-pragma-2"); testOrderOfMultipleHeadersIsPreservedOnRequests("Pragma", request); } @Test public void testOrderOfMultipleViaHeadersIsPreservedOnRequests() throws Exception { request.addHeader("Via", "1.0 fred, 1.1 nowhere.com (Apache/1.1)"); request.addHeader("Via", "1.0 ricky, 1.1 mertz, 1.0 lucy"); testOrderOfMultipleHeadersIsPreservedOnRequests("Via", request); } @Test public void testOrderOfMultipleWarningHeadersIsPreservedOnRequests() throws Exception { request.addHeader("Warning", "199 fred \"bargle\""); request.addHeader("Warning", "199 barney \"bungle\""); testOrderOfMultipleHeadersIsPreservedOnRequests("Warning", request); } private void testOrderOfMultipleHeadersIsPreservedOnResponses(final String h) throws Exception { EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertNotNull(result); Assert.assertEquals(HttpTestUtils.getCanonicalHeaderValue(originResponse, h), HttpTestUtils .getCanonicalHeaderValue(result, h)); } @Test public void testOrderOfMultipleAllowHeadersIsPreservedOnResponses() throws Exception { originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, 405, "Method Not Allowed")); originResponse.addHeader("Allow", "HEAD"); originResponse.addHeader("Allow", "DELETE"); testOrderOfMultipleHeadersIsPreservedOnResponses("Allow"); } @Test public void testOrderOfMultipleCacheControlHeadersIsPreservedOnResponses() throws Exception { originResponse.addHeader("Cache-Control", "max-age=0"); originResponse.addHeader("Cache-Control", "no-store, must-revalidate"); testOrderOfMultipleHeadersIsPreservedOnResponses("Cache-Control"); } @Test public void testOrderOfMultipleContentEncodingHeadersIsPreservedOnResponses() throws Exception { originResponse.addHeader("Content-Encoding", "gzip"); originResponse.addHeader("Content-Encoding", "compress"); testOrderOfMultipleHeadersIsPreservedOnResponses("Content-Encoding"); } @Test public void testOrderOfMultipleContentLanguageHeadersIsPreservedOnResponses() throws Exception { originResponse.addHeader("Content-Language", "mi"); originResponse.addHeader("Content-Language", "en"); testOrderOfMultipleHeadersIsPreservedOnResponses("Content-Language"); } @Test public void testOrderOfMultiplePragmaHeadersIsPreservedOnResponses() throws Exception { originResponse.addHeader("Pragma", "no-cache, x-pragma-2"); originResponse.addHeader("Pragma", "x-pragma-1"); testOrderOfMultipleHeadersIsPreservedOnResponses("Pragma"); } @Test public void testOrderOfMultipleViaHeadersIsPreservedOnResponses() throws Exception { originResponse.addHeader("Via", "1.0 fred, 1.1 nowhere.com (Apache/1.1)"); originResponse.addHeader("Via", "1.0 ricky, 1.1 mertz, 1.0 lucy"); testOrderOfMultipleHeadersIsPreservedOnResponses("Via"); } @Test public void testOrderOfMultipleWWWAuthenticateHeadersIsPreservedOnResponses() throws Exception { originResponse.addHeader("WWW-Authenticate", "x-challenge-1"); originResponse.addHeader("WWW-Authenticate", "x-challenge-2"); testOrderOfMultipleHeadersIsPreservedOnResponses("WWW-Authenticate"); } /* * "However, applications MUST understand the class of any status code, as * indicated by the first digit, and treat any unrecognized response as * being equivalent to the x00 status code of that class, with the exception * that an unrecognized response MUST NOT be cached." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1 */ private void testUnknownResponseStatusCodeIsNotCached(final int code) throws Exception { emptyMockCacheExpectsNoPuts(); originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, code, "Moo")); originResponse.setHeader("Date", DateUtils.formatDate(new Date())); originResponse.setHeader("Server", "MockOrigin/1.0"); originResponse.setHeader("Cache-Control", "max-age=3600"); originResponse.setEntity(body); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); // in particular, there were no storage calls on the cache verifyMocks(); } @Test public void testUnknownResponseStatusCodesAreNotCached() throws Exception { for (int i = 102; i <= 199; i++) { testUnknownResponseStatusCodeIsNotCached(i); } for (int i = 207; i <= 299; i++) { testUnknownResponseStatusCodeIsNotCached(i); } for (int i = 308; i <= 399; i++) { testUnknownResponseStatusCodeIsNotCached(i); } for (int i = 418; i <= 499; i++) { testUnknownResponseStatusCodeIsNotCached(i); } for (int i = 506; i <= 999; i++) { testUnknownResponseStatusCodeIsNotCached(i); } } /* * "Unrecognized header fields SHOULD be ignored by the recipient and MUST * be forwarded by transparent proxies." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.1 */ @Test public void testUnknownHeadersOnRequestsAreForwarded() throws Exception { request.addHeader("X-Unknown-Header", "blahblah"); final Capture reqCap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.capture(reqCap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); final HttpRequest forwarded = reqCap.getValue(); final Header[] hdrs = forwarded.getHeaders("X-Unknown-Header"); Assert.assertEquals(1, hdrs.length); Assert.assertEquals("blahblah", hdrs[0].getValue()); } @Test public void testUnknownHeadersOnResponsesAreForwarded() throws Exception { originResponse.addHeader("X-Unknown-Header", "blahblah"); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); final Header[] hdrs = result.getHeaders("X-Unknown-Header"); Assert.assertEquals(1, hdrs.length); Assert.assertEquals("blahblah", hdrs[0].getValue()); } /* * "If a client will wait for a 100 (Continue) response before sending the * request body, it MUST send an Expect request-header field (section 14.20) * with the '100-continue' expectation." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3 */ @Test public void testRequestsExpecting100ContinueBehaviorShouldSetExpectHeader() throws Exception { final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest( "POST", "/", HttpVersion.HTTP_1_1); post.setHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE); post.setHeader("Content-Length", "128"); post.setEntity(new BasicHttpEntity()); final Capture reqCap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(reqCap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, HttpRequestWrapper.wrap(post), context, null); verifyMocks(); final HttpRequestWrapper forwarded = reqCap.getValue(); boolean foundExpect = false; for (final Header h : forwarded.getHeaders("Expect")) { for (final HeaderElement elt : h.getElements()) { if ("100-continue".equalsIgnoreCase(elt.getName())) { foundExpect = true; break; } } } Assert.assertTrue(foundExpect); } /* * "If a client will wait for a 100 (Continue) response before sending the * request body, it MUST send an Expect request-header field (section 14.20) * with the '100-continue' expectation." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3 */ @Test public void testRequestsNotExpecting100ContinueBehaviorShouldNotSetExpectContinueHeader() throws Exception { final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest( "POST", "/", HttpVersion.HTTP_1_1); post.setHeader("Content-Length", "128"); post.setEntity(new BasicHttpEntity()); final Capture reqCap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(reqCap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, HttpRequestWrapper.wrap(post), context, null); verifyMocks(); final HttpRequestWrapper forwarded = reqCap.getValue(); boolean foundExpect = false; for (final Header h : forwarded.getHeaders("Expect")) { for (final HeaderElement elt : h.getElements()) { if ("100-continue".equalsIgnoreCase(elt.getName())) { foundExpect = true; break; } } } Assert.assertFalse(foundExpect); } /* * "A client MUST NOT send an Expect request-header field (section 14.20) * with the '100-continue' expectation if it does not intend to send a * request body." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3 */ @Test public void testExpect100ContinueIsNotSentIfThereIsNoRequestBody() throws Exception { request.addHeader("Expect", "100-continue"); final Capture reqCap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(reqCap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); final HttpRequest forwarded = reqCap.getValue(); boolean foundExpectContinue = false; for (final Header h : forwarded.getHeaders("Expect")) { for (final HeaderElement elt : h.getElements()) { if ("100-continue".equalsIgnoreCase(elt.getName())) { foundExpectContinue = true; break; } } } Assert.assertFalse(foundExpectContinue); } /* * "If a proxy receives a request that includes an Expect request- header * field with the '100-continue' expectation, and the proxy either knows * that the next-hop server complies with HTTP/1.1 or higher, or does not * know the HTTP version of the next-hop server, it MUST forward the * request, including the Expect header field. * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3 */ @Test public void testExpectHeadersAreForwardedOnRequests() throws Exception { // This would mostly apply to us if we were part of an // application that was a proxy, and would be the // responsibility of the greater application. Our // responsibility is to make sure that if we get an // entity-enclosing request that we properly set (or unset) // the Expect header per the request.expectContinue() flag, // which is tested by the previous few tests. } /* * "A proxy MUST NOT forward a 100 (Continue) response if the request * message was received from an HTTP/1.0 (or earlier) client and did not * include an Expect request-header field with the '100-continue' * expectation. This requirement overrides the general rule for forwarding * of 1xx responses (see section 10.1)." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3 */ @Test public void test100ContinueResponsesAreNotForwardedTo1_0ClientsWhoDidNotAskForThem() throws Exception { final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/", new ProtocolVersion("HTTP", 1, 0)); post.setEntity(body); post.setHeader("Content-Length", "128"); originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue")); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); try { // if a 100 response gets up to us from the HttpClient // backend, we can't really handle it at that point impl.execute(route, HttpRequestWrapper.wrap(post), context, null); Assert.fail("should have thrown an exception"); } catch (final ClientProtocolException expected) { } verifyMocks(); } /* * "9.2 OPTIONS. ...Responses to this method are not cacheable. * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2 */ @Test public void testResponsesToOPTIONSAreNotCacheable() throws Exception { emptyMockCacheExpectsNoPuts(); request = HttpRequestWrapper.wrap(new BasicHttpRequest("OPTIONS", "/", HttpVersion.HTTP_1_1)); originResponse.addHeader("Cache-Control", "max-age=3600"); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); } /* * "A 200 response SHOULD .... If no response body is included, the response * MUST include a Content-Length field with a field-value of '0'." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2 */ @Test public void test200ResponseToOPTIONSWithNoBodyShouldIncludeContentLengthZero() throws Exception { request = HttpRequestWrapper.wrap(new BasicHttpRequest("OPTIONS", "/", HttpVersion.HTTP_1_1)); originResponse.setEntity(null); originResponse.setHeader("Content-Length", "0"); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); final Header contentLength = result.getFirstHeader("Content-Length"); Assert.assertNotNull(contentLength); Assert.assertEquals("0", contentLength.getValue()); } /* * "When a proxy receives an OPTIONS request on an absoluteURI for which * request forwarding is permitted, the proxy MUST check for a Max-Forwards * field. If the Max-Forwards field-value is zero ("0"), the proxy MUST NOT * forward the message; instead, the proxy SHOULD respond with its own * communication options." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2 */ @Test public void testDoesNotForwardOPTIONSWhenMaxForwardsIsZeroOnAbsoluteURIRequest() throws Exception { request = HttpRequestWrapper.wrap(new BasicHttpRequest("OPTIONS", "*", HttpVersion.HTTP_1_1)); request.setHeader("Max-Forwards", "0"); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); } /* * "If the Max-Forwards field-value is an integer greater than zero, the * proxy MUST decrement the field-value when it forwards the request." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2 */ @Test public void testDecrementsMaxForwardsWhenForwardingOPTIONSRequest() throws Exception { request = HttpRequestWrapper.wrap(new BasicHttpRequest("OPTIONS", "*", HttpVersion.HTTP_1_1)); request.setHeader("Max-Forwards", "7"); final Capture cap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); final HttpRequest captured = cap.getValue(); Assert.assertEquals("6", captured.getFirstHeader("Max-Forwards").getValue()); } /* * "If no Max-Forwards field is present in the request, then the forwarded * request MUST NOT include a Max-Forwards field." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2 */ @Test public void testDoesNotAddAMaxForwardsHeaderToForwardedOPTIONSRequests() throws Exception { request = HttpRequestWrapper.wrap(new BasicHttpRequest("OPTIONS", "/", HttpVersion.HTTP_1_1)); final Capture reqCap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(reqCap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); final HttpRequest forwarded = reqCap.getValue(); Assert.assertNull(forwarded.getFirstHeader("Max-Forwards")); } /* * "The HEAD method is identical to GET except that the server MUST NOT * return a message-body in the response." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4 */ @Test public void testResponseToAHEADRequestMustNotHaveABody() throws Exception { request = HttpRequestWrapper.wrap(new BasicHttpRequest("HEAD", "/", HttpVersion.HTTP_1_1)); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertTrue(result.getEntity() == null || result.getEntity().getContentLength() == 0); } /* * "If the new field values indicate that the cached entity differs from the * current entity (as would be indicated by a change in Content-Length, * Content-MD5, ETag or Last-Modified), then the cache MUST treat the cache * entry as stale." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4 */ private void testHEADResponseWithUpdatedEntityFieldsMakeACacheEntryStale(final String eHeader, final String oldVal, final String newVal) throws Exception { // put something cacheable in the cache final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.addHeader("Cache-Control", "max-age=3600"); resp1.setHeader(eHeader, oldVal); // get a head that penetrates the cache final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("HEAD", "/", HttpVersion.HTTP_1_1)); req2.addHeader("Cache-Control", "no-cache"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setEntity(null); resp2.setHeader(eHeader, newVal); // next request doesn't tolerate stale entry final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req3.addHeader("Cache-Control", "max-stale=0"); final HttpResponse resp3 = HttpTestUtils.make200Response(); resp3.setHeader(eHeader, newVal); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), eqRequest(req1), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), eqRequest(req2), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp3)); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); impl.execute(route, req3, context, null); verifyMocks(); } @Test public void testHEADResponseWithUpdatedContentLengthFieldMakeACacheEntryStale() throws Exception { testHEADResponseWithUpdatedEntityFieldsMakeACacheEntryStale("Content-Length", "128", "127"); } @Test public void testHEADResponseWithUpdatedContentMD5FieldMakeACacheEntryStale() throws Exception { testHEADResponseWithUpdatedEntityFieldsMakeACacheEntryStale("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ==", "Q2hlY2sgSW50ZWdyaXR5IR=="); } @Test public void testHEADResponseWithUpdatedETagFieldMakeACacheEntryStale() throws Exception { testHEADResponseWithUpdatedEntityFieldsMakeACacheEntryStale("ETag", "\"etag1\"", "\"etag2\""); } @Test public void testHEADResponseWithUpdatedLastModifiedFieldMakeACacheEntryStale() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); testHEADResponseWithUpdatedEntityFieldsMakeACacheEntryStale("Last-Modified", DateUtils .formatDate(tenSecondsAgo), DateUtils.formatDate(sixSecondsAgo)); } /* * "9.5 POST. Responses to this method are not cacheable, unless the * response includes appropriate Cache-Control or Expires header fields." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5 */ @Test public void testResponsesToPOSTWithoutCacheControlOrExpiresAreNotCached() throws Exception { emptyMockCacheExpectsNoPuts(); final BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest("POST", "/", HttpVersion.HTTP_1_1); post.setHeader("Content-Length", "128"); post.setEntity(HttpTestUtils.makeBody(128)); originResponse.removeHeaders("Cache-Control"); originResponse.removeHeaders("Expires"); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, HttpRequestWrapper.wrap(post), context, null); verifyMocks(); } /* * "9.5 PUT. ...Responses to this method are not cacheable." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6 */ @Test public void testResponsesToPUTsAreNotCached() throws Exception { emptyMockCacheExpectsNoPuts(); final BasicHttpEntityEnclosingRequest put = new BasicHttpEntityEnclosingRequest("PUT", "/", HttpVersion.HTTP_1_1); put.setEntity(HttpTestUtils.makeBody(128)); put.addHeader("Content-Length", "128"); originResponse.setHeader("Cache-Control", "max-age=3600"); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, HttpRequestWrapper.wrap(put), context, null); verifyMocks(); } /* * "9.6 DELETE. ... Responses to this method are not cacheable." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7 */ @Test public void testResponsesToDELETEsAreNotCached() throws Exception { emptyMockCacheExpectsNoPuts(); request = HttpRequestWrapper.wrap(new BasicHttpRequest("DELETE", "/", HttpVersion.HTTP_1_1)); originResponse.setHeader("Cache-Control", "max-age=3600"); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); } /* * "A TRACE request MUST NOT include an entity." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.8 */ @Test public void testForwardedTRACERequestsDoNotIncludeAnEntity() throws Exception { final BasicHttpEntityEnclosingRequest trace = new BasicHttpEntityEnclosingRequest("TRACE", "/", HttpVersion.HTTP_1_1); trace.setEntity(HttpTestUtils.makeBody(entityLength)); trace.setHeader("Content-Length", Integer.toString(entityLength)); final Capture reqCap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(reqCap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, HttpRequestWrapper.wrap(trace), context, null); verifyMocks(); final HttpRequest forwarded = reqCap.getValue(); if (forwarded instanceof HttpEntityEnclosingRequest) { final HttpEntityEnclosingRequest bodyReq = (HttpEntityEnclosingRequest) forwarded; Assert.assertTrue(bodyReq.getEntity() == null || bodyReq.getEntity().getContentLength() == 0); } else { // request didn't enclose an entity } } /* * "9.8 TRACE ... Responses to this method MUST NOT be cached." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.8 */ @Test public void testResponsesToTRACEsAreNotCached() throws Exception { emptyMockCacheExpectsNoPuts(); request = HttpRequestWrapper.wrap(new BasicHttpRequest("TRACE", "/", HttpVersion.HTTP_1_1)); originResponse.setHeader("Cache-Control", "max-age=3600"); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); } /* * "The 204 response MUST NOT include a message-body, and thus is always * terminated by the first empty line after the header fields." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5 */ @Test public void test204ResponsesDoNotContainMessageBodies() throws Exception { originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, "No Content")); originResponse.setEntity(HttpTestUtils.makeBody(entityLength)); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertTrue(result.getEntity() == null || result.getEntity().getContentLength() == 0); } /* * "10.2.6 205 Reset Content ... The response MUST NOT include an entity." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.6 */ @Test public void test205ResponsesDoNotContainMessageBodies() throws Exception { originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_RESET_CONTENT, "Reset Content")); originResponse.setEntity(HttpTestUtils.makeBody(entityLength)); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertTrue(result.getEntity() == null || result.getEntity().getContentLength() == 0); } /* * "The [206] response MUST include the following header fields: * * - Either a Content-Range header field (section 14.16) indicating the * range included with this response, or a multipart/byteranges Content-Type * including Content-Range fields for each part. If a Content-Length header * field is present in the response, its value MUST match the actual number * of OCTETs transmitted in the message-body. * * - Date * * - ETag and/or Content-Location, if the header would have been sent in a * 200 response to the same request * * - Expires, Cache-Control, and/or Vary, if the field-value might differ * from that sent in any previous response for the same variant" * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7 */ @Test public void test206ResponseGeneratedFromCacheMustHaveContentRangeOrMultipartByteRangesContentType() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Cache-Control", "max-age=3600"); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Range", "bytes=0-50"); backendExpectsAnyRequestAndReturn(resp1).times(1, 2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (HttpStatus.SC_PARTIAL_CONTENT == result.getStatusLine().getStatusCode()) { if (result.getFirstHeader("Content-Range") == null) { final HeaderElement elt = result.getFirstHeader("Content-Type").getElements()[0]; Assert.assertTrue("multipart/byteranges".equalsIgnoreCase(elt.getName())); Assert.assertNotNull(elt.getParameterByName("boundary")); Assert.assertNotNull(elt.getParameterByName("boundary").getValue()); Assert.assertFalse("".equals(elt.getParameterByName("boundary").getValue().trim())); } } } @Test public void test206ResponseGeneratedFromCacheMustHaveABodyThatMatchesContentLengthHeaderIfPresent() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Cache-Control", "max-age=3600"); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Range", "bytes=0-50"); backendExpectsAnyRequestAndReturn(resp1).times(1, 2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (HttpStatus.SC_PARTIAL_CONTENT == result.getStatusLine().getStatusCode()) { final Header h = result.getFirstHeader("Content-Length"); if (h != null) { final int contentLength = Integer.parseInt(h.getValue()); int bytesRead = 0; final InputStream i = result.getEntity().getContent(); while ((i.read()) != -1) { bytesRead++; } i.close(); Assert.assertEquals(contentLength, bytesRead); } } } @Test public void test206ResponseGeneratedFromCacheMustHaveDateHeader() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Cache-Control", "max-age=3600"); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Range", "bytes=0-50"); backendExpectsAnyRequestAndReturn(resp1).times(1, 2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (HttpStatus.SC_PARTIAL_CONTENT == result.getStatusLine().getStatusCode()) { Assert.assertNotNull(result.getFirstHeader("Date")); } } @Test public void test206ResponseReturnedToClientMustHaveDateHeader() throws Exception { request.addHeader("Range", "bytes=0-50"); originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content")); originResponse.setHeader("Date", DateUtils.formatDate(new Date())); originResponse.setHeader("Server", "MockOrigin/1.0"); originResponse.setEntity(HttpTestUtils.makeBody(500)); originResponse.setHeader("Content-Range", "bytes 0-499/1234"); originResponse.removeHeaders("Date"); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); Assert.assertTrue(result.getStatusLine().getStatusCode() != HttpStatus.SC_PARTIAL_CONTENT || result.getFirstHeader("Date") != null); verifyMocks(); } @Test public void test206ContainsETagIfA200ResponseWouldHaveIncludedIt() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); originResponse.addHeader("Cache-Control", "max-age=3600"); originResponse.addHeader("ETag", "\"etag1\""); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.addHeader("Range", "bytes=0-50"); backendExpectsAnyRequest().andReturn(originResponse).times(1, 2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (result.getStatusLine().getStatusCode() == HttpStatus.SC_PARTIAL_CONTENT) { Assert.assertNotNull(result.getFirstHeader("ETag")); } } @Test public void test206ContainsContentLocationIfA200ResponseWouldHaveIncludedIt() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); originResponse.addHeader("Cache-Control", "max-age=3600"); originResponse.addHeader("Content-Location", "http://foo.example.com/other/url"); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.addHeader("Range", "bytes=0-50"); backendExpectsAnyRequest().andReturn(originResponse).times(1, 2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (result.getStatusLine().getStatusCode() == HttpStatus.SC_PARTIAL_CONTENT) { Assert.assertNotNull(result.getFirstHeader("Content-Location")); } } @Test public void test206ResponseIncludesVariantHeadersIfValueMightDiffer() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.addHeader("Accept-Encoding", "gzip"); final Date now = new Date(); final Date inOneHour = new Date(now.getTime() + 3600 * 1000L); originResponse.addHeader("Cache-Control", "max-age=3600"); originResponse.addHeader("Expires", DateUtils.formatDate(inOneHour)); originResponse.addHeader("Vary", "Accept-Encoding"); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.addHeader("Cache-Control", "no-cache"); req2.addHeader("Accept-Encoding", "gzip"); final Date nextSecond = new Date(now.getTime() + 1000L); final Date inTwoHoursPlusASec = new Date(now.getTime() + 2 * 3600 * 1000L + 1000L); final HttpResponse originResponse2 = HttpTestUtils.make200Response(); originResponse2.setHeader("Date", DateUtils.formatDate(nextSecond)); originResponse2.setHeader("Cache-Control", "max-age=7200"); originResponse2.setHeader("Expires", DateUtils.formatDate(inTwoHoursPlusASec)); originResponse2.setHeader("Vary", "Accept-Encoding"); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req3.addHeader("Range", "bytes=0-50"); req3.addHeader("Accept-Encoding", "gzip"); backendExpectsAnyRequest().andReturn(originResponse); backendExpectsAnyRequestAndReturn(originResponse2).times(1, 2); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); final HttpResponse result = impl.execute(route, req3, context, null); verifyMocks(); if (result.getStatusLine().getStatusCode() == HttpStatus.SC_PARTIAL_CONTENT) { Assert.assertNotNull(result.getFirstHeader("Expires")); Assert.assertNotNull(result.getFirstHeader("Cache-Control")); Assert.assertNotNull(result.getFirstHeader("Vary")); } } /* * "If the [206] response is the result of an If-Range request that used a * weak validator, the response MUST NOT include other entity-headers; this * prevents inconsistencies between cached entity-bodies and updated * headers." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7 */ @Test public void test206ResponseToConditionalRangeRequestDoesNotIncludeOtherEntityHeaders() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final Date now = new Date(); final Date oneHourAgo = new Date(now.getTime() - 3600 * 1000L); originResponse = Proxies.enhanceResponse(HttpTestUtils.make200Response()); originResponse.addHeader("Allow", "GET,HEAD"); originResponse.addHeader("Cache-Control", "max-age=3600"); originResponse.addHeader("Content-Language", "en"); originResponse.addHeader("Content-Encoding", "x-coding"); originResponse.addHeader("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ=="); originResponse.addHeader("Content-Length", "128"); originResponse.addHeader("Content-Type", "application/octet-stream"); originResponse.addHeader("Last-Modified", DateUtils.formatDate(oneHourAgo)); originResponse.addHeader("ETag", "W/\"weak-tag\""); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.addHeader("If-Range", "W/\"weak-tag\""); req2.addHeader("Range", "bytes=0-50"); backendExpectsAnyRequest().andReturn(originResponse).times(1, 2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (result.getStatusLine().getStatusCode() == HttpStatus.SC_PARTIAL_CONTENT) { Assert.assertNull(result.getFirstHeader("Allow")); Assert.assertNull(result.getFirstHeader("Content-Encoding")); Assert.assertNull(result.getFirstHeader("Content-Language")); Assert.assertNull(result.getFirstHeader("Content-MD5")); Assert.assertNull(result.getFirstHeader("Last-Modified")); } } /* * "Otherwise, the [206] response MUST include all of the entity-headers * that would have been returned with a 200 (OK) response to the same * [If-Range] request." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7 */ @Test public void test206ResponseToIfRangeWithStrongValidatorReturnsAllEntityHeaders() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final Date now = new Date(); final Date oneHourAgo = new Date(now.getTime() - 3600 * 1000L); originResponse.addHeader("Allow", "GET,HEAD"); originResponse.addHeader("Cache-Control", "max-age=3600"); originResponse.addHeader("Content-Language", "en"); originResponse.addHeader("Content-Encoding", "x-coding"); originResponse.addHeader("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ=="); originResponse.addHeader("Content-Length", "128"); originResponse.addHeader("Content-Type", "application/octet-stream"); originResponse.addHeader("Last-Modified", DateUtils.formatDate(oneHourAgo)); originResponse.addHeader("ETag", "\"strong-tag\""); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.addHeader("If-Range", "\"strong-tag\""); req2.addHeader("Range", "bytes=0-50"); backendExpectsAnyRequest().andReturn(originResponse).times(1, 2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (result.getStatusLine().getStatusCode() == HttpStatus.SC_PARTIAL_CONTENT) { Assert.assertEquals("GET,HEAD", result.getFirstHeader("Allow").getValue()); Assert.assertEquals("max-age=3600", result.getFirstHeader("Cache-Control").getValue()); Assert.assertEquals("en", result.getFirstHeader("Content-Language").getValue()); Assert.assertEquals("x-coding", result.getFirstHeader("Content-Encoding").getValue()); Assert.assertEquals("Q2hlY2sgSW50ZWdyaXR5IQ==", result.getFirstHeader("Content-MD5") .getValue()); Assert.assertEquals(originResponse.getFirstHeader("Last-Modified").getValue(), result .getFirstHeader("Last-Modified").getValue()); } } /* * "A cache MUST NOT combine a 206 response with other previously cached * content if the ETag or Last-Modified headers do not match exactly, see * 13.5.4." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7 */ @Test public void test206ResponseIsNotCombinedWithPreviousContentIfETagDoesNotMatch() throws Exception { final Date now = new Date(); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("ETag", "\"etag1\""); final byte[] bytes1 = new byte[128]; for (int i = 0; i < bytes1.length; i++) { bytes1[i] = (byte) 1; } resp1.setEntity(new ByteArrayEntity(bytes1)); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Cache-Control", "no-cache"); req2.setHeader("Range", "bytes=0-50"); final Date inOneSecond = new Date(now.getTime() + 1000L); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp2.setHeader("Date", DateUtils.formatDate(inOneSecond)); resp2.setHeader("Server", resp1.getFirstHeader("Server").getValue()); resp2.setHeader("ETag", "\"etag2\""); resp2.setHeader("Content-Range", "bytes 0-50/128"); final byte[] bytes2 = new byte[51]; for (int i = 0; i < bytes2.length; i++) { bytes2[i] = (byte) 2; } resp2.setEntity(new ByteArrayEntity(bytes2)); final Date inTwoSeconds = new Date(now.getTime() + 2000L); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp3 = HttpTestUtils.make200Response(); resp3.setHeader("Date", DateUtils.formatDate(inTwoSeconds)); resp3.setHeader("Cache-Control", "max-age=3600"); resp3.setHeader("ETag", "\"etag2\""); final byte[] bytes3 = new byte[128]; for (int i = 0; i < bytes3.length; i++) { bytes3[i] = (byte) 2; } resp3.setEntity(new ByteArrayEntity(bytes3)); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp1)); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp3)).times(0, 1); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); final HttpResponse result = impl.execute(route, req3, context, null); verifyMocks(); final InputStream i = result.getEntity().getContent(); int b; boolean found1 = false; boolean found2 = false; while ((b = i.read()) != -1) { if (b == 1) { found1 = true; } if (b == 2) { found2 = true; } } i.close(); Assert.assertFalse(found1 && found2); // mixture of content } @Test public void test206ResponseIsNotCombinedWithPreviousContentIfLastModifiedDoesNotMatch() throws Exception { final Date now = new Date(); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); final Date oneHourAgo = new Date(now.getTime() - 3600L); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("Last-Modified", DateUtils.formatDate(oneHourAgo)); final byte[] bytes1 = new byte[128]; for (int i = 0; i < bytes1.length; i++) { bytes1[i] = (byte) 1; } resp1.setEntity(new ByteArrayEntity(bytes1)); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Cache-Control", "no-cache"); req2.setHeader("Range", "bytes=0-50"); final Date inOneSecond = new Date(now.getTime() + 1000L); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp2.setHeader("Date", DateUtils.formatDate(inOneSecond)); resp2.setHeader("Server", resp1.getFirstHeader("Server").getValue()); resp2.setHeader("Last-Modified", DateUtils.formatDate(now)); resp2.setHeader("Content-Range", "bytes 0-50/128"); final byte[] bytes2 = new byte[51]; for (int i = 0; i < bytes2.length; i++) { bytes2[i] = (byte) 2; } resp2.setEntity(new ByteArrayEntity(bytes2)); final Date inTwoSeconds = new Date(now.getTime() + 2000L); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp3 = HttpTestUtils.make200Response(); resp3.setHeader("Date", DateUtils.formatDate(inTwoSeconds)); resp3.setHeader("Cache-Control", "max-age=3600"); resp3.setHeader("ETag", "\"etag2\""); final byte[] bytes3 = new byte[128]; for (int i = 0; i < bytes3.length; i++) { bytes3[i] = (byte) 2; } resp3.setEntity(new ByteArrayEntity(bytes3)); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp1)); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp3)).times(0, 1); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); final HttpResponse result = impl.execute(route, req3, context, null); verifyMocks(); final InputStream i = result.getEntity().getContent(); int b; boolean found1 = false; boolean found2 = false; while ((b = i.read()) != -1) { if (b == 1) { found1 = true; } if (b == 2) { found2 = true; } } i.close(); Assert.assertFalse(found1 && found2); // mixture of content } /* * "A cache that does not support the Range and Content-Range headers MUST * NOT cache 206 (Partial) responses." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7 */ @Test public void test206ResponsesAreNotCachedIfTheCacheDoesNotSupportRangeAndContentRangeHeaders() throws Exception { if (!supportsRangeAndContentRangeHeaders(impl)) { emptyMockCacheExpectsNoPuts(); request = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); request.addHeader("Range", "bytes=0-50"); originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content")); originResponse.setHeader("Content-Range", "bytes 0-50/128"); originResponse.setHeader("Cache-Control", "max-age=3600"); final byte[] bytes = new byte[51]; new Random().nextBytes(bytes); originResponse.setEntity(new ByteArrayEntity(bytes)); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); } } /* * "10.3.4 303 See Other ... The 303 response MUST NOT be cached, but the * response to the second (redirected) request might be cacheable." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4 */ @Test public void test303ResponsesAreNotCached() throws Exception { emptyMockCacheExpectsNoPuts(); request = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_SEE_OTHER, "See Other")); originResponse.setHeader("Date", DateUtils.formatDate(new Date())); originResponse.setHeader("Server", "MockServer/1.0"); originResponse.setHeader("Cache-Control", "max-age=3600"); originResponse.setHeader("Content-Type", "application/x-cachingclient-test"); originResponse.setHeader("Location", "http://foo.example.com/other"); originResponse.setEntity(HttpTestUtils.makeBody(entityLength)); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); } /* * "The 304 response MUST NOT contain a message-body, and thus is always * terminated by the first empty line after the header fields." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5 */ @Test public void test304ResponseDoesNotContainABody() throws Exception { request.setHeader("If-None-Match", "\"etag\""); originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified")); originResponse.setHeader("Date", DateUtils.formatDate(new Date())); originResponse.setHeader("Server", "MockServer/1.0"); originResponse.setHeader("Content-Length", "128"); originResponse.setEntity(HttpTestUtils.makeBody(entityLength)); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertTrue(result.getEntity() == null || result.getEntity().getContentLength() == 0); } /* * "The [304] response MUST include the following header fields: - Date, * unless its omission is required by section 14.18.1 [clockless origin * servers]." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5 */ @Test public void test304ResponseWithDateHeaderForwardedFromOriginIncludesDateHeader() throws Exception { request.setHeader("If-None-Match", "\"etag\""); originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified")); originResponse.setHeader("Date", DateUtils.formatDate(new Date())); originResponse.setHeader("Server", "MockServer/1.0"); originResponse.setHeader("ETag", "\"etag\""); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertNotNull(result.getFirstHeader("Date")); } @Test public void test304ResponseGeneratedFromCacheIncludesDateHeader() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); originResponse.setHeader("Cache-Control", "max-age=3600"); originResponse.setHeader("ETag", "\"etag\""); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("If-None-Match", "\"etag\""); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse).times(1, 2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (result.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_MODIFIED) { Assert.assertNotNull(result.getFirstHeader("Date")); } } /* * "The [304] response MUST include the following header fields: - ETag * and/or Content-Location, if the header would have been sent in a 200 * response to the same request." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5 */ @Test public void test304ResponseGeneratedFromCacheIncludesEtagIfOriginResponseDid() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); originResponse.setHeader("Cache-Control", "max-age=3600"); originResponse.setHeader("ETag", "\"etag\""); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("If-None-Match", "\"etag\""); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse).times(1, 2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (result.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_MODIFIED) { Assert.assertNotNull(result.getFirstHeader("ETag")); } } @Test public void test304ResponseGeneratedFromCacheIncludesContentLocationIfOriginResponseDid() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); originResponse.setHeader("Cache-Control", "max-age=3600"); originResponse.setHeader("Content-Location", "http://foo.example.com/other"); originResponse.setHeader("ETag", "\"etag\""); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("If-None-Match", "\"etag\""); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse).times(1, 2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (result.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_MODIFIED) { Assert.assertNotNull(result.getFirstHeader("Content-Location")); } } /* * "The [304] response MUST include the following header fields: ... - * Expires, Cache-Control, and/or Vary, if the field-value might differ from * that sent in any previous response for the same variant * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5 */ @Test public void test304ResponseGeneratedFromCacheIncludesExpiresCacheControlAndOrVaryIfResponseMightDiffer() throws Exception { final Date now = new Date(); final Date inTwoHours = new Date(now.getTime() + 2 * 3600 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("Accept-Encoding", "gzip"); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag", "\"v1\""); resp1.setHeader("Cache-Control", "max-age=7200"); resp1.setHeader("Expires", DateUtils.formatDate(inTwoHours)); resp1.setHeader("Vary", "Accept-Encoding"); resp1.setEntity(HttpTestUtils.makeBody(entityLength)); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("Accept-Encoding", "gzip"); req1.setHeader("Cache-Control", "no-cache"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag", "\"v2\""); resp2.setHeader("Cache-Control", "max-age=3600"); resp2.setHeader("Expires", DateUtils.formatDate(inTwoHours)); resp2.setHeader("Vary", "Accept-Encoding"); resp2.setEntity(HttpTestUtils.makeBody(entityLength)); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req3.setHeader("Accept-Encoding", "gzip"); req3.setHeader("If-None-Match", "\"v2\""); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp1)); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)).times(1, 2); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); final HttpResponse result = impl.execute(route, req3, context, null); verifyMocks(); if (result.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_MODIFIED) { Assert.assertNotNull(result.getFirstHeader("Expires")); Assert.assertNotNull(result.getFirstHeader("Cache-Control")); Assert.assertNotNull(result.getFirstHeader("Vary")); } } /* * "Otherwise (i.e., the conditional GET used a weak validator), the * response MUST NOT include other entity-headers; this prevents * inconsistencies between cached entity-bodies and updated headers." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5 */ @Test public void test304GeneratedFromCacheOnWeakValidatorDoesNotIncludeOtherEntityHeaders() throws Exception { final Date now = new Date(); final Date oneHourAgo = new Date(now.getTime() - 3600 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag", "W/\"v1\""); resp1.setHeader("Allow", "GET,HEAD"); resp1.setHeader("Content-Encoding", "x-coding"); resp1.setHeader("Content-Language", "en"); resp1.setHeader("Content-Length", "128"); resp1.setHeader("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ=="); resp1.setHeader("Content-Type", "application/octet-stream"); resp1.setHeader("Last-Modified", DateUtils.formatDate(oneHourAgo)); resp1.setHeader("Cache-Control", "max-age=7200"); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("If-None-Match", "W/\"v1\""); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp1)).times(1, 2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (result.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_MODIFIED) { Assert.assertNull(result.getFirstHeader("Allow")); Assert.assertNull(result.getFirstHeader("Content-Encoding")); Assert.assertNull(result.getFirstHeader("Content-Length")); Assert.assertNull(result.getFirstHeader("Content-MD5")); Assert.assertNull(result.getFirstHeader("Content-Type")); Assert.assertNull(result.getFirstHeader("Last-Modified")); } } /* * "If a 304 response indicates an entity not currently cached, then the * cache MUST disregard the response and repeat the request without the * conditional." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5 */ @Test public void testNotModifiedOfNonCachedEntityShouldRevalidateWithUnconditionalGET() throws Exception { final Date now = new Date(); // load cache with cacheable entry final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag", "\"etag1\""); resp1.setHeader("Cache-Control", "max-age=3600"); // force a revalidation final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Cache-Control", "max-age=0,max-stale=0"); // updated ETag provided to a conditional revalidation final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader("Server", "MockServer/1.0"); resp2.setHeader("ETag", "\"etag2\""); // conditional validation uses If-None-Match final HttpRequestWrapper conditionalValidation = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); conditionalValidation.setHeader("If-None-Match", "\"etag1\""); // unconditional validation doesn't use If-None-Match final HttpRequestWrapper unconditionalValidation = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); // new response to unconditional validation provides new body final HttpResponse resp3 = HttpTestUtils.make200Response(); resp1.setHeader("ETag", "\"etag2\""); resp1.setHeader("Cache-Control", "max-age=3600"); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp1)); // this next one will happen once if the cache tries to // conditionally validate, zero if it goes full revalidation EasyMock.expect( mockBackend.execute( EasyMock.eq(route), eqRequest(conditionalValidation), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)).times(0, 1); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), eqRequest(unconditionalValidation), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp3)); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); } /* * "If a cache uses a received 304 response to update a cache entry, the * cache MUST update the entry to reflect any new field values given in the * response. * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5 */ @Test public void testCacheEntryIsUpdatedWithNewFieldValuesIn304Response() throws Exception { final Date now = new Date(); final Date inFiveSeconds = new Date(now.getTime() + 5000L); final HttpRequestWrapper initialRequest = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse cachedResponse = HttpTestUtils.make200Response(); cachedResponse.setHeader("Cache-Control", "max-age=3600"); cachedResponse.setHeader("ETag", "\"etag\""); final HttpRequestWrapper secondRequest = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); secondRequest.setHeader("Cache-Control", "max-age=0,max-stale=0"); final HttpRequestWrapper conditionalValidationRequest = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); conditionalValidationRequest.setHeader("If-None-Match", "\"etag\""); final HttpRequestWrapper unconditionalValidationRequest = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); // to be used if the cache generates a conditional validation final HttpResponse conditionalResponse = new BasicHttpResponse( HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); conditionalResponse.setHeader("Date", DateUtils.formatDate(inFiveSeconds)); conditionalResponse.setHeader("Server", "MockUtils/1.0"); conditionalResponse.setHeader("ETag", "\"etag\""); conditionalResponse.setHeader("X-Extra", "junk"); // to be used if the cache generates an unconditional validation final HttpResponse unconditionalResponse = HttpTestUtils.make200Response(); unconditionalResponse.setHeader("Date", DateUtils.formatDate(inFiveSeconds)); unconditionalResponse.setHeader("ETag", "\"etag\""); final Capture cap1 = new Capture(); final Capture cap2 = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(cachedResponse)); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.and(eqRequest(conditionalValidationRequest), EasyMock.capture(cap1)), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(conditionalResponse)).times(0, 1); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.and(eqRequest(unconditionalValidationRequest), EasyMock.capture(cap2)), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(unconditionalResponse)).times(0, 1); replayMocks(); impl.execute(route, initialRequest, context, null); final HttpResponse result = impl.execute(route, secondRequest, context, null); verifyMocks(); Assert.assertTrue((cap1.hasCaptured() && !cap2.hasCaptured()) || (!cap1.hasCaptured() && cap2.hasCaptured())); if (cap1.hasCaptured()) { Assert.assertEquals(DateUtils.formatDate(inFiveSeconds), result.getFirstHeader("Date") .getValue()); Assert.assertEquals("junk", result.getFirstHeader("X-Extra").getValue()); } } /* * "10.4.2 401 Unauthorized ... The response MUST include a WWW-Authenticate * header field (section 14.47) containing a challenge applicable to the * requested resource." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2 */ @Test public void testMustIncludeWWWAuthenticateHeaderOnAnOrigin401Response() throws Exception { originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, 401, "Unauthorized")); originResponse.setHeader("WWW-Authenticate", "x-scheme x-param"); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); if (result.getStatusLine().getStatusCode() == 401) { Assert.assertNotNull(result.getFirstHeader("WWW-Authenticate")); } verifyMocks(); } /* * "10.4.6 405 Method Not Allowed ... The response MUST include an Allow * header containing a list of valid methods for the requested resource. * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2 */ @Test public void testMustIncludeAllowHeaderFromAnOrigin405Response() throws Exception { originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, 405, "Method Not Allowed")); originResponse.setHeader("Allow", "GET, HEAD"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); if (result.getStatusLine().getStatusCode() == 405) { Assert.assertNotNull(result.getFirstHeader("Allow")); } verifyMocks(); } /* * "10.4.8 407 Proxy Authentication Required ... The proxy MUST return a * Proxy-Authenticate header field (section 14.33) containing a challenge * applicable to the proxy for the requested resource." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8 */ @Test public void testMustIncludeProxyAuthenticateHeaderFromAnOrigin407Response() throws Exception { originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, 407, "Proxy Authentication Required")); originResponse.setHeader("Proxy-Authenticate", "x-scheme x-param"); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); if (result.getStatusLine().getStatusCode() == 407) { Assert.assertNotNull(result.getFirstHeader("Proxy-Authenticate")); } verifyMocks(); } /* * "10.4.17 416 Requested Range Not Satisfiable ... This response MUST NOT * use the multipart/byteranges content-type." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.17 */ @Test public void testMustNotAddMultipartByteRangeContentTypeTo416Response() throws Exception { originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, 416, "Requested Range Not Satisfiable")); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); if (result.getStatusLine().getStatusCode() == 416) { for (final Header h : result.getHeaders("Content-Type")) { for (final HeaderElement elt : h.getElements()) { Assert.assertFalse("multipart/byteranges".equalsIgnoreCase(elt.getName())); } } } } @Test public void testMustNotUseMultipartByteRangeContentTypeOnCacheGenerated416Responses() throws Exception { originResponse.setEntity(HttpTestUtils.makeBody(entityLength)); originResponse.setHeader("Content-Length", "128"); originResponse.setHeader("Cache-Control", "max-age=3600"); final HttpRequestWrapper rangeReq = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); rangeReq.setHeader("Range", "bytes=1000-1200"); final HttpResponse orig416 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 416, "Requested Range Not Satisfiable"); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); // cache may 416 me right away if it understands byte ranges, // ok to delegate to origin though EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(orig416)).times(0, 1); replayMocks(); impl.execute(route, request, context, null); final HttpResponse result = impl.execute(route, rangeReq, context, null); verifyMocks(); // might have gotten a 416 from the origin or the cache if (result.getStatusLine().getStatusCode() == 416) { for (final Header h : result.getHeaders("Content-Type")) { for (final HeaderElement elt : h.getElements()) { Assert.assertFalse("multipart/byteranges".equalsIgnoreCase(elt.getName())); } } } } /* * "A correct cache MUST respond to a request with the most up-to-date * response held by the cache that is appropriate to the request (see * sections 13.2.5, 13.2.6, and 13.12) which meets one of the following * conditions: * * 1. It has been checked for equivalence with what the origin server would * have returned by revalidating the response with the origin server * (section 13.3); * * 2. It is "fresh enough" (see section 13.2). In the default case, this * means it meets the least restrictive freshness requirement of the client, * origin server, and cache (see section 14.9); if the origin server so * specifies, it is the freshness requirement of the origin server alone. * * If a stored response is not "fresh enough" by the most restrictive * freshness requirement of both the client and the origin server, in * carefully considered circumstances the cache MAY still return the * response with the appropriate Warning header (see section 13.1.5 and * 14.46), unless such a response is prohibited (e.g., by a "no-store" * cache-directive, or by a "no-cache" cache-request-directive; see section * 14.9). * * 3. It is an appropriate 304 (Not Modified), 305 (Proxy Redirect), or * error (4xx or 5xx) response message." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.1.1 */ @Test public void testMustReturnACacheEntryIfItCanRevalidateIt() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Date nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); final Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L); final Header[] hdrs = new Header[] { new BasicHeader("Date", DateUtils.formatDate(nineSecondsAgo)), new BasicHeader("Cache-Control", "max-age=0"), new BasicHeader("ETag", "\"etag\""), new BasicHeader("Content-Length", "128") }; final byte[] bytes = new byte[128]; new Random().nextBytes(bytes); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes); impl = new CachingExec(mockBackend, mockCache, config); request = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1)); final HttpRequestWrapper validate = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1)); validate.setHeader("If-None-Match", "\"etag\""); final CloseableHttpResponse notModified = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified")); notModified.setHeader("Date", DateUtils.formatDate(now)); notModified.setHeader("ETag", "\"etag\""); mockCache.flushInvalidatedCacheEntriesFor(EasyMock.eq(host), eqRequest(request)); EasyMock.expect( mockCache.getCacheEntry(EasyMock.eq(host), eqRequest(request))) .andReturn(entry); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), eqRequest(validate), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(notModified); EasyMock.expect(mockCache.updateCacheEntry( EasyMock.eq(host), eqRequest(request), EasyMock.eq(entry), eqResponse(notModified), EasyMock.isA(Date.class), EasyMock.isA(Date.class))) .andReturn(HttpTestUtils.makeCacheEntry()); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); } @Test public void testMustReturnAFreshEnoughCacheEntryIfItHasIt() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Date nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); final Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L); final Header[] hdrs = new Header[] { new BasicHeader("Date", DateUtils.formatDate(nineSecondsAgo)), new BasicHeader("Cache-Control", "max-age=3600"), new BasicHeader("Content-Length", "128") }; final byte[] bytes = new byte[128]; new Random().nextBytes(bytes); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes); impl = new CachingExec(mockBackend, mockCache, config); request = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1)); mockCache.flushInvalidatedCacheEntriesFor(EasyMock.eq(host), eqRequest(request)); EasyMock.expect(mockCache.getCacheEntry(EasyMock.eq(host), eqRequest(request))).andReturn(entry); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertEquals(200, result.getStatusLine().getStatusCode()); } /* * "If the cache can not communicate with the origin server, then a correct * cache SHOULD respond as above if the response can be correctly served * from the cache; if not it MUST return an error or warning indicating that * there was a communication failure." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.1.1 * * "111 Revalidation failed MUST be included if a cache returns a stale * response because an attempt to revalidate the response failed, due to an * inability to reach the server." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.46 */ @Test public void testMustServeAppropriateErrorOrWarningIfNoOriginCommunicationPossible() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Date nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); final Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L); final Header[] hdrs = new Header[] { new BasicHeader("Date", DateUtils.formatDate(nineSecondsAgo)), new BasicHeader("Cache-Control", "max-age=0"), new BasicHeader("Content-Length", "128"), new BasicHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo)) }; final byte[] bytes = new byte[128]; new Random().nextBytes(bytes); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes); impl = new CachingExec(mockBackend, mockCache, config); request = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1)); mockCache.flushInvalidatedCacheEntriesFor(EasyMock.eq(host), eqRequest(request)); EasyMock.expect(mockCache.getCacheEntry(EasyMock.eq(host), eqRequest(request))).andReturn(entry); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andThrow( new IOException("can't talk to origin!")).anyTimes(); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); final int status = result.getStatusLine().getStatusCode(); if (status == 200) { boolean foundWarning = false; for (final Header h : result.getHeaders("Warning")) { if (h.getValue().split(" ")[0].equals("111")) { foundWarning = true; } } Assert.assertTrue(foundWarning); } else { Assert.assertTrue(status >= 500 && status <= 599); } } /* * "Whenever a cache returns a response that is neither first-hand nor * "fresh enough" (in the sense of condition 2 in section 13.1.1), it MUST * attach a warning to that effect, using a Warning general-header." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.1.2 */ @Test public void testAttachesWarningHeaderWhenGeneratingStaleResponse() throws Exception { // covered by previous test } /* * "1xx Warnings that describe the freshness or revalidation status of the * response, and so MUST be deleted after a successful revalidation." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.1.2 */ @Test public void test1xxWarningsAreDeletedAfterSuccessfulRevalidation() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 25 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Cache-Control", "max-age=5"); resp1.setHeader("Warning", "110 squid \"stale stuff\""); resp1.setHeader("Via", "1.1 fred"); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpRequestWrapper validate = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); validate.setHeader("If-None-Match", "\"etag\""); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader("Server", "MockServer/1.0"); resp2.setHeader("ETag", "\"etag\""); resp2.setHeader("Via", "1.1 fred"); backendExpectsAnyRequestAndReturn(resp1); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), eqRequest(validate), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); replayMocks(); final HttpResponse stale = impl.execute(route, req1, context, null); Assert.assertNotNull(stale.getFirstHeader("Warning")); final HttpResponse result1 = impl.execute(route, req2, context, null); final HttpResponse result2 = impl.execute(route, req3, context, null); verifyMocks(); boolean found1xxWarning = false; for (final Header h : result1.getHeaders("Warning")) { for (final HeaderElement elt : h.getElements()) { if (elt.getName().startsWith("1")) { found1xxWarning = true; } } } for (final Header h : result2.getHeaders("Warning")) { for (final HeaderElement elt : h.getElements()) { if (elt.getName().startsWith("1")) { found1xxWarning = true; } } } Assert.assertFalse(found1xxWarning); } /* * "2xx Warnings that describe some aspect of the entity body or entity * headers that is not rectified by a revalidation (for example, a lossy * compression of the entity bodies) and which MUST NOT be deleted after a * successful revalidation." * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.1.2 */ @Test public void test2xxWarningsAreNotDeletedAfterSuccessfulRevalidation() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("ETag", "\"etag\""); resp1.setHeader("Cache-Control", "max-age=5"); resp1.setHeader("Via", "1.1 xproxy"); resp1.setHeader("Warning", "214 xproxy \"transformed stuff\""); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpRequestWrapper validate = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); validate.setHeader("If-None-Match", "\"etag\""); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp2.setHeader("Date", DateUtils.formatDate(now)); resp2.setHeader("Server", "MockServer/1.0"); resp2.setHeader("ETag", "\"etag\""); resp1.setHeader("Via", "1.1 xproxy"); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); backendExpectsAnyRequestAndReturn(resp1); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), eqRequest(validate), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)); replayMocks(); final HttpResponse stale = impl.execute(route, req1, context, null); Assert.assertNotNull(stale.getFirstHeader("Warning")); final HttpResponse result1 = impl.execute(route, req2, context, null); final HttpResponse result2 = impl.execute(route, req3, context, null); verifyMocks(); boolean found214Warning = false; for (final Header h : result1.getHeaders("Warning")) { for (final HeaderElement elt : h.getElements()) { final String[] parts = elt.getName().split(" "); if ("214".equals(parts[0])) { found214Warning = true; } } } Assert.assertTrue(found214Warning); found214Warning = false; for (final Header h : result2.getHeaders("Warning")) { for (final HeaderElement elt : h.getElements()) { final String[] parts = elt.getName().split(" "); if ("214".equals(parts[0])) { found214Warning = true; } } } Assert.assertTrue(found214Warning); } /* * "When a response is generated from a cache entry, the cache MUST include * a single Age header field in the response with a value equal to the cache * entry's current_age." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.3 */ @Test public void testAgeHeaderPopulatedFromCacheEntryCurrentAge() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Date nineSecondsAgo = new Date(now.getTime() - 9 * 1000L); final Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L); final Header[] hdrs = new Header[] { new BasicHeader("Date", DateUtils.formatDate(nineSecondsAgo)), new BasicHeader("Cache-Control", "max-age=3600"), new BasicHeader("Content-Length", "128") }; final byte[] bytes = new byte[128]; new Random().nextBytes(bytes); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes); impl = new CachingExec(mockBackend, mockCache, config); request = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1)); mockCache.flushInvalidatedCacheEntriesFor(EasyMock.eq(host), eqRequest(request)); EasyMock.expect(mockCache.getCacheEntry(EasyMock.eq(host), eqRequest(request))).andReturn(entry); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertEquals(200, result.getStatusLine().getStatusCode()); Assert.assertEquals("11", result.getFirstHeader("Age").getValue()); } /* * "If none of Expires, Cache-Control: max-age, or Cache-Control: s-maxage * (see section 14.9.3) appears in the response, and the response does not * include other restrictions on caching, the cache MAY compute a freshness * lifetime using a heuristic. The cache MUST attach Warning 113 to any * response whose age is more than 24 hours if such warning has not already * been added." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.4 * * "113 Heuristic expiration MUST be included if the cache heuristically * chose a freshness lifetime greater than 24 hours and the response's age * is greater than 24 hours." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.46 */ @Test public void testHeuristicCacheOlderThan24HoursHasWarningAttached() throws Exception { final Date now = new Date(); final Date thirtySixHoursAgo = new Date(now.getTime() - 36 * 3600 * 1000L); final Date oneYearAgo = new Date(now.getTime() - 365 * 24 * 3600 * 1000L); final Date requestTime = new Date(thirtySixHoursAgo.getTime() - 1000L); final Date responseTime = new Date(thirtySixHoursAgo.getTime() + 1000L); final Header[] hdrs = new Header[] { new BasicHeader("Date", DateUtils.formatDate(thirtySixHoursAgo)), new BasicHeader("Cache-Control", "public"), new BasicHeader("Last-Modified", DateUtils.formatDate(oneYearAgo)), new BasicHeader("Content-Length", "128") }; final byte[] bytes = new byte[128]; new Random().nextBytes(bytes); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(requestTime, responseTime, hdrs, bytes); impl = new CachingExec(mockBackend, mockCache, config); request = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1)); final CloseableHttpResponse validated = Proxies.enhanceResponse(HttpTestUtils.make200Response()); validated.setHeader("Cache-Control", "public"); validated.setHeader("Last-Modified", DateUtils.formatDate(oneYearAgo)); validated.setHeader("Content-Length", "128"); validated.setEntity(new ByteArrayEntity(bytes)); final CloseableHttpResponse reconstructed = Proxies.enhanceResponse(HttpTestUtils.make200Response()); final Capture cap = new Capture(); mockCache.flushInvalidatedCacheEntriesFor(EasyMock.eq(host), eqRequest(request)); mockCache.flushInvalidatedCacheEntriesFor( EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpResponse.class)); EasyMock.expect(mockCache.getCacheEntry(EasyMock.eq(host), eqRequest(request))).andReturn(entry); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(validated).times(0, 1); EasyMock.expect(mockCache.getCacheEntry( EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequestWrapper.class))).andReturn(entry).times(0, 1); EasyMock.expect(mockCache.cacheAndReturnResponse( EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequestWrapper.class), eqCloseableResponse(validated), EasyMock.isA(Date.class), EasyMock.isA(Date.class))).andReturn(reconstructed).times(0, 1); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertEquals(200, result.getStatusLine().getStatusCode()); if (!cap.hasCaptured()) { // heuristic cache hit boolean found113Warning = false; for (final Header h : result.getHeaders("Warning")) { for (final HeaderElement elt : h.getElements()) { final String[] parts = elt.getName().split(" "); if ("113".equals(parts[0])) { found113Warning = true; break; } } } Assert.assertTrue(found113Warning); } } /* * "If a cache has two fresh responses for the same representation with * different validators, it MUST use the one with the more recent Date * header." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.5 */ @Test public void testKeepsMostRecentDateHeaderForFreshResponse() throws Exception { final Date now = new Date(); final Date inFiveSecond = new Date(now.getTime() + 5 * 1000L); // put an entry in the cache final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(inFiveSecond)); resp1.setHeader("ETag", "\"etag1\""); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("Content-Length", "128"); // force another origin hit final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Cache-Control", "no-cache"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Date", DateUtils.formatDate(now)); // older resp2.setHeader("ETag", "\"etag2\""); resp2.setHeader("Cache-Control", "max-age=3600"); resp2.setHeader("Content-Length", "128"); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), eqRequest(req1), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp1)); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); final HttpResponse result = impl.execute(route, req3, context, null); verifyMocks(); Assert.assertEquals("\"etag1\"", result.getFirstHeader("ETag").getValue()); } /* * "Clients MAY issue simple (non-subrange) GET requests with either weak * validators or strong validators. Clients MUST NOT use weak validators in * other forms of request." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.3 * * Note that we can't determine a priori whether a given HTTP-date is a weak * or strong validator, because that might depend on an upstream client * having a cache with a Last-Modified and Date entry that allows the date * to be a strong validator. We can tell when *we* are generating a request * for validation, but we can't tell if we receive a conditional request * from upstream. */ private HttpResponse testRequestWithWeakETagValidatorIsNotAllowed(final String header) throws Exception { final Capture cap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse).times(0, 1); replayMocks(); final HttpResponse response = impl.execute(route, request, context, null); verifyMocks(); // it's probably ok to return a 400 (Bad Request) to this client if (cap.hasCaptured()) { final HttpRequest forwarded = cap.getValue(); final Header h = forwarded.getFirstHeader(header); if (h != null) { Assert.assertFalse(h.getValue().startsWith("W/")); } } return response; } @Test public void testSubrangeGETWithWeakETagIsNotAllowed() throws Exception { request = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); request.setHeader("Range", "bytes=0-500"); request.setHeader("If-Range", "W/\"etag\""); final HttpResponse response = testRequestWithWeakETagValidatorIsNotAllowed("If-Range"); Assert.assertTrue(response.getStatusLine().getStatusCode() == HttpStatus.SC_BAD_REQUEST); } @Test public void testPUTWithIfMatchWeakETagIsNotAllowed() throws Exception { final HttpEntityEnclosingRequest put = new BasicHttpEntityEnclosingRequest("PUT", "/", HttpVersion.HTTP_1_1); put.setEntity(HttpTestUtils.makeBody(128)); put.setHeader("Content-Length", "128"); put.setHeader("If-Match", "W/\"etag\""); request = HttpRequestWrapper.wrap(put); testRequestWithWeakETagValidatorIsNotAllowed("If-Match"); } @Test public void testPUTWithIfNoneMatchWeakETagIsNotAllowed() throws Exception { final HttpEntityEnclosingRequest put = new BasicHttpEntityEnclosingRequest("PUT", "/", HttpVersion.HTTP_1_1); put.setEntity(HttpTestUtils.makeBody(128)); put.setHeader("Content-Length", "128"); put.setHeader("If-None-Match", "W/\"etag\""); request = HttpRequestWrapper.wrap(put); testRequestWithWeakETagValidatorIsNotAllowed("If-None-Match"); } @Test public void testDELETEWithIfMatchWeakETagIsNotAllowed() throws Exception { request = HttpRequestWrapper.wrap( new BasicHttpRequest("DELETE", "/", HttpVersion.HTTP_1_1)); request.setHeader("If-Match", "W/\"etag\""); testRequestWithWeakETagValidatorIsNotAllowed("If-Match"); } @Test public void testDELETEWithIfNoneMatchWeakETagIsNotAllowed() throws Exception { request = HttpRequestWrapper.wrap( new BasicHttpRequest("DELETE", "/", HttpVersion.HTTP_1_1)); request.setHeader("If-None-Match", "W/\"etag\""); testRequestWithWeakETagValidatorIsNotAllowed("If-None-Match"); } /* * "A cache or origin server receiving a conditional request, other than a * full-body GET request, MUST use the strong comparison function to * evaluate the condition." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.3 */ @Test public void testSubrangeGETMustUseStrongComparisonForCachedResponse() throws Exception { final Date now = new Date(); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("ETag", "\"etag\""); // according to weak comparison, this would match. Strong // comparison doesn't, because the cache entry's ETag is not // marked weak. Therefore, the If-Range must fail and we must // either get an error back or the full entity, but we better // not get the conditionally-requested Partial Content (206). final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Range", "bytes=0-50"); req2.setHeader("If-Range", "W/\"etag\""); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp1)).times(1, 2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertFalse(HttpStatus.SC_PARTIAL_CONTENT == result.getStatusLine().getStatusCode()); } /* * "HTTP/1.1 clients: - If an entity tag has been provided by the origin * server, MUST use that entity tag in any cache-conditional request (using * If- Match or If-None-Match)." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.4 */ @Test public void testValidationMustUseETagIfProvidedByOriginServer() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("ETag", "W/\"etag\""); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Cache-Control", "max-age=0,max-stale=0"); final Capture cap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp1)); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp1)); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); final HttpRequest validation = cap.getValue(); boolean isConditional = false; final String[] conditionalHeaders = { "If-Range", "If-Modified-Since", "If-Unmodified-Since", "If-Match", "If-None-Match" }; for (final String ch : conditionalHeaders) { if (validation.getFirstHeader(ch) != null) { isConditional = true; break; } } if (isConditional) { boolean foundETag = false; for (final Header h : validation.getHeaders("If-Match")) { for (final HeaderElement elt : h.getElements()) { if ("W/\"etag\"".equals(elt.getName())) { foundETag = true; } } } for (final Header h : validation.getHeaders("If-None-Match")) { for (final HeaderElement elt : h.getElements()) { if ("W/\"etag\"".equals(elt.getName())) { foundETag = true; } } } Assert.assertTrue(foundETag); } } /* * "An HTTP/1.1 caching proxy, upon receiving a conditional request that * includes both a Last-Modified date and one or more entity tags as cache * validators, MUST NOT return a locally cached response to the client * unless that cached response is consistent with all of the conditional * header fields in the request." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.4 */ @Test public void testConditionalRequestWhereNotAllValidatorsMatchCannotBeServedFromCache() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final Date twentySecondsAgo = new Date(now.getTime() - 20 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("ETag", "W/\"etag\""); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("If-None-Match", "W/\"etag\""); req2.setHeader("If-Modified-Since", DateUtils.formatDate(twentySecondsAgo)); // must hit the origin again for the second request EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp1)).times(2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertFalse(HttpStatus.SC_NOT_MODIFIED == result.getStatusLine().getStatusCode()); } @Test public void testConditionalRequestWhereAllValidatorsMatchMayBeServedFromCache() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(now)); resp1.setHeader("Cache-Control", "max-age=3600"); resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("ETag", "W/\"etag\""); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("If-None-Match", "W/\"etag\""); req2.setHeader("If-Modified-Since", DateUtils.formatDate(tenSecondsAgo)); // may hit the origin again for the second request EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp1)).times(1,2); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); } /* * "However, a cache that does not support the Range and Content-Range * headers MUST NOT cache 206 (Partial Content) responses." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.4 */ @Test public void testCacheWithoutSupportForRangeAndContentRangeHeadersDoesNotCacheA206Response() throws Exception { if (!supportsRangeAndContentRangeHeaders(impl)) { emptyMockCacheExpectsNoPuts(); final HttpRequestWrapper req = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req.setHeader("Range", "bytes=0-50"); final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, 206, "Partial Content"); resp.setHeader("Content-Range", "bytes 0-50/128"); resp.setHeader("ETag", "\"etag\""); resp.setHeader("Cache-Control", "max-age=3600"); EasyMock.expect(mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.isA(HttpRequestWrapper.class), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(Proxies.enhanceResponse(resp)); replayMocks(); impl.execute(route, req, context, null); verifyMocks(); } } /* * "A response received with any other status code (e.g. status codes 302 * and 307) MUST NOT be returned in a reply to a subsequent request unless * there are cache-control directives or another header(s) that explicitly * allow it. For example, these include the following: an Expires header * (section 14.21); a 'max-age', 's-maxage', 'must-revalidate', * 'proxy-revalidate', 'public' or 'private' cache-control directive * (section 14.9)." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.4 */ @Test public void test302ResponseWithoutExplicitCacheabilityIsNotReturnedFromCache() throws Exception { originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, 302, "Temporary Redirect")); originResponse.setHeader("Location", "http://foo.example.com/other"); originResponse.removeHeaders("Expires"); originResponse.removeHeaders("Cache-Control"); backendExpectsAnyRequest().andReturn(originResponse).times(2); replayMocks(); impl.execute(route, request, context, null); impl.execute(route, request, context, null); verifyMocks(); } /* * "A transparent proxy MUST NOT modify any of the following fields in a * request or response, and it MUST NOT add any of these fields if not * already present: - Content-Location - Content-MD5 - ETag - Last-Modified */ private void testDoesNotModifyHeaderFromOrigin(final String header, final String value) throws Exception { originResponse = Proxies.enhanceResponse(HttpTestUtils.make200Response()); originResponse.setHeader(header, value); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertEquals(value, result.getFirstHeader(header).getValue()); } @Test public void testDoesNotModifyContentLocationHeaderFromOrigin() throws Exception { final String url = "http://foo.example.com/other"; testDoesNotModifyHeaderFromOrigin("Content-Location", url); } @Test public void testDoesNotModifyContentMD5HeaderFromOrigin() throws Exception { testDoesNotModifyHeaderFromOrigin("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ=="); } @Test public void testDoesNotModifyEtagHeaderFromOrigin() throws Exception { testDoesNotModifyHeaderFromOrigin("Etag", "\"the-etag\""); } @Test public void testDoesNotModifyLastModifiedHeaderFromOrigin() throws Exception { final String lm = DateUtils.formatDate(new Date()); testDoesNotModifyHeaderFromOrigin("Last-Modified", lm); } private void testDoesNotAddHeaderToOriginResponse(final String header) throws Exception { originResponse.removeHeaders(header); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertNull(result.getFirstHeader(header)); } @Test public void testDoesNotAddContentLocationToOriginResponse() throws Exception { testDoesNotAddHeaderToOriginResponse("Content-Location"); } @Test public void testDoesNotAddContentMD5ToOriginResponse() throws Exception { testDoesNotAddHeaderToOriginResponse("Content-MD5"); } @Test public void testDoesNotAddEtagToOriginResponse() throws Exception { testDoesNotAddHeaderToOriginResponse("ETag"); } @Test public void testDoesNotAddLastModifiedToOriginResponse() throws Exception { testDoesNotAddHeaderToOriginResponse("Last-Modified"); } private void testDoesNotModifyHeaderFromOriginOnCacheHit(final String header, final String value) throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); originResponse = Proxies.enhanceResponse(HttpTestUtils.make200Response()); originResponse.setHeader("Cache-Control", "max-age=3600"); originResponse.setHeader(header, value); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(value, result.getFirstHeader(header).getValue()); } @Test public void testDoesNotModifyContentLocationFromOriginOnCacheHit() throws Exception { final String url = "http://foo.example.com/other"; testDoesNotModifyHeaderFromOriginOnCacheHit("Content-Location", url); } @Test public void testDoesNotModifyContentMD5FromOriginOnCacheHit() throws Exception { testDoesNotModifyHeaderFromOriginOnCacheHit("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ=="); } @Test public void testDoesNotModifyEtagFromOriginOnCacheHit() throws Exception { testDoesNotModifyHeaderFromOriginOnCacheHit("Etag", "\"the-etag\""); } @Test public void testDoesNotModifyLastModifiedFromOriginOnCacheHit() throws Exception { final String lm = DateUtils.formatDate(new Date(System.currentTimeMillis() - 10 * 1000L)); testDoesNotModifyHeaderFromOriginOnCacheHit("Last-Modified", lm); } private void testDoesNotAddHeaderOnCacheHit(final String header) throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); originResponse.addHeader("Cache-Control", "max-age=3600"); originResponse.removeHeaders(header); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertNull(result.getFirstHeader(header)); } @Test public void testDoesNotAddContentLocationHeaderOnCacheHit() throws Exception { testDoesNotAddHeaderOnCacheHit("Content-Location"); } @Test public void testDoesNotAddContentMD5HeaderOnCacheHit() throws Exception { testDoesNotAddHeaderOnCacheHit("Content-MD5"); } @Test public void testDoesNotAddETagHeaderOnCacheHit() throws Exception { testDoesNotAddHeaderOnCacheHit("ETag"); } @Test public void testDoesNotAddLastModifiedHeaderOnCacheHit() throws Exception { testDoesNotAddHeaderOnCacheHit("Last-Modified"); } private void testDoesNotModifyHeaderOnRequest(final String header, final String value) throws Exception { final BasicHttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("POST","/",HttpVersion.HTTP_1_1); req.setEntity(HttpTestUtils.makeBody(128)); req.setHeader("Content-Length","128"); req.setHeader(header,value); final Capture cap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, HttpRequestWrapper.wrap(req), context, null); verifyMocks(); final HttpRequest captured = cap.getValue(); Assert.assertEquals(value, captured.getFirstHeader(header).getValue()); } @Test public void testDoesNotModifyContentLocationHeaderOnRequest() throws Exception { final String url = "http://foo.example.com/other"; testDoesNotModifyHeaderOnRequest("Content-Location",url); } @Test public void testDoesNotModifyContentMD5HeaderOnRequest() throws Exception { testDoesNotModifyHeaderOnRequest("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ=="); } @Test public void testDoesNotModifyETagHeaderOnRequest() throws Exception { testDoesNotModifyHeaderOnRequest("ETag","\"etag\""); } @Test public void testDoesNotModifyLastModifiedHeaderOnRequest() throws Exception { final long tenSecondsAgo = System.currentTimeMillis() - 10 * 1000L; final String lm = DateUtils.formatDate(new Date(tenSecondsAgo)); testDoesNotModifyHeaderOnRequest("Last-Modified", lm); } private void testDoesNotAddHeaderToRequestIfNotPresent(final String header) throws Exception { final BasicHttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("POST","/",HttpVersion.HTTP_1_1); req.setEntity(HttpTestUtils.makeBody(128)); req.setHeader("Content-Length","128"); req.removeHeaders(header); final Capture cap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, HttpRequestWrapper.wrap(req), context, null); verifyMocks(); final HttpRequest captured = cap.getValue(); Assert.assertNull(captured.getFirstHeader(header)); } @Test public void testDoesNotAddContentLocationToRequestIfNotPresent() throws Exception { testDoesNotAddHeaderToRequestIfNotPresent("Content-Location"); } @Test public void testDoesNotAddContentMD5ToRequestIfNotPresent() throws Exception { testDoesNotAddHeaderToRequestIfNotPresent("Content-MD5"); } @Test public void testDoesNotAddETagToRequestIfNotPresent() throws Exception { testDoesNotAddHeaderToRequestIfNotPresent("ETag"); } @Test public void testDoesNotAddLastModifiedToRequestIfNotPresent() throws Exception { testDoesNotAddHeaderToRequestIfNotPresent("Last-Modified"); } /* " A transparent proxy MUST NOT modify any of the following * fields in a response: - Expires * but it MAY add any of these fields if not already present. If * an Expires header is added, it MUST be given a field-value * identical to that of the Date header in that response. */ @Test public void testDoesNotModifyExpiresHeaderFromOrigin() throws Exception { final long inTenSeconds = System.currentTimeMillis() + 10 * 1000L; final String expires = DateUtils.formatDate(new Date(inTenSeconds)); testDoesNotModifyHeaderFromOrigin("Expires", expires); } @Test public void testDoesNotModifyExpiresHeaderFromOriginOnCacheHit() throws Exception { final long inTenSeconds = System.currentTimeMillis() + 10 * 1000L; final String expires = DateUtils.formatDate(new Date(inTenSeconds)); testDoesNotModifyHeaderFromOriginOnCacheHit("Expires", expires); } @Test public void testExpiresHeaderMatchesDateIfAddedToOriginResponse() throws Exception { originResponse.removeHeaders("Expires"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); final Header expHdr = result.getFirstHeader("Expires"); if (expHdr != null) { Assert.assertEquals(result.getFirstHeader("Date").getValue(), expHdr.getValue()); } } @Test public void testExpiresHeaderMatchesDateIfAddedToCacheHit() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); originResponse.setHeader("Cache-Control","max-age=3600"); originResponse.removeHeaders("Expires"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); final Header expHdr = result.getFirstHeader("Expires"); if (expHdr != null) { Assert.assertEquals(result.getFirstHeader("Date").getValue(), expHdr.getValue()); } } /* "A proxy MUST NOT modify or add any of the following fields in * a message that contains the no-transform cache-control * directive, or in any request: - Content-Encoding - Content-Range * - Content-Type" * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.2 */ private void testDoesNotModifyHeaderFromOriginResponseWithNoTransform(final String header, final String value) throws Exception { originResponse.addHeader("Cache-Control","no-transform"); originResponse.setHeader(header, value); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertEquals(value, result.getFirstHeader(header).getValue()); } @Test public void testDoesNotModifyContentEncodingHeaderFromOriginResponseWithNoTransform() throws Exception { testDoesNotModifyHeaderFromOriginResponseWithNoTransform("Content-Encoding","gzip"); } @Test public void testDoesNotModifyContentRangeHeaderFromOriginResponseWithNoTransform() throws Exception { request.setHeader("If-Range","\"etag\""); request.setHeader("Range","bytes=0-49"); originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_1, 206, "Partial Content")); originResponse.setEntity(HttpTestUtils.makeBody(50)); testDoesNotModifyHeaderFromOriginResponseWithNoTransform("Content-Range","bytes 0-49/128"); } @Test public void testDoesNotModifyContentTypeHeaderFromOriginResponseWithNoTransform() throws Exception { testDoesNotModifyHeaderFromOriginResponseWithNoTransform("Content-Type","text/html;charset=utf-8"); } private void testDoesNotModifyHeaderOnCachedResponseWithNoTransform(final String header, final String value) throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); originResponse.addHeader("Cache-Control","max-age=3600, no-transform"); originResponse.setHeader(header, value); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(value, result.getFirstHeader(header).getValue()); } @Test public void testDoesNotModifyContentEncodingHeaderOnCachedResponseWithNoTransform() throws Exception { testDoesNotModifyHeaderOnCachedResponseWithNoTransform("Content-Encoding","gzip"); } @Test public void testDoesNotModifyContentTypeHeaderOnCachedResponseWithNoTransform() throws Exception { testDoesNotModifyHeaderOnCachedResponseWithNoTransform("Content-Type","text/html;charset=utf-8"); } @Test public void testDoesNotModifyContentRangeHeaderOnCachedResponseWithNoTransform() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("If-Range","\"etag\""); req1.setHeader("Range","bytes=0-49"); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("If-Range","\"etag\""); req2.setHeader("Range","bytes=0-49"); originResponse.addHeader("Cache-Control","max-age=3600, no-transform"); originResponse.setHeader("Content-Range", "bytes 0-49/128"); backendExpectsAnyRequest().andReturn(originResponse).times(1,2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals("bytes 0-49/128", result.getFirstHeader("Content-Range").getValue()); } @Test public void testDoesNotAddContentEncodingHeaderToOriginResponseWithNoTransformIfNotPresent() throws Exception { originResponse.addHeader("Cache-Control","no-transform"); testDoesNotAddHeaderToOriginResponse("Content-Encoding"); } @Test public void testDoesNotAddContentRangeHeaderToOriginResponseWithNoTransformIfNotPresent() throws Exception { originResponse.addHeader("Cache-Control","no-transform"); testDoesNotAddHeaderToOriginResponse("Content-Range"); } @Test public void testDoesNotAddContentTypeHeaderToOriginResponseWithNoTransformIfNotPresent() throws Exception { originResponse.addHeader("Cache-Control","no-transform"); testDoesNotAddHeaderToOriginResponse("Content-Type"); } /* no add on cache hit with no-transform */ @Test public void testDoesNotAddContentEncodingHeaderToCachedResponseWithNoTransformIfNotPresent() throws Exception { originResponse.addHeader("Cache-Control","no-transform"); testDoesNotAddHeaderOnCacheHit("Content-Encoding"); } @Test public void testDoesNotAddContentRangeHeaderToCachedResponseWithNoTransformIfNotPresent() throws Exception { originResponse.addHeader("Cache-Control","no-transform"); testDoesNotAddHeaderOnCacheHit("Content-Range"); } @Test public void testDoesNotAddContentTypeHeaderToCachedResponseWithNoTransformIfNotPresent() throws Exception { originResponse.addHeader("Cache-Control","no-transform"); testDoesNotAddHeaderOnCacheHit("Content-Type"); } /* no modify on request */ @Test public void testDoesNotAddContentEncodingToRequestIfNotPresent() throws Exception { testDoesNotAddHeaderToRequestIfNotPresent("Content-Encoding"); } @Test public void testDoesNotAddContentRangeToRequestIfNotPresent() throws Exception { testDoesNotAddHeaderToRequestIfNotPresent("Content-Range"); } @Test public void testDoesNotAddContentTypeToRequestIfNotPresent() throws Exception { testDoesNotAddHeaderToRequestIfNotPresent("Content-Type"); } @Test public void testDoesNotAddContentEncodingHeaderToRequestIfNotPresent() throws Exception { testDoesNotAddHeaderToRequestIfNotPresent("Content-Encoding"); } @Test public void testDoesNotAddContentRangeHeaderToRequestIfNotPresent() throws Exception { testDoesNotAddHeaderToRequestIfNotPresent("Content-Range"); } @Test public void testDoesNotAddContentTypeHeaderToRequestIfNotPresent() throws Exception { testDoesNotAddHeaderToRequestIfNotPresent("Content-Type"); } /* "When a cache makes a validating request to a server, and the * server provides a 304 (Not Modified) response or a 206 (Partial * Content) response, the cache then constructs a response to send * to the requesting client. * * If the status code is 304 (Not Modified), the cache uses the * entity-body stored in the cache entry as the entity-body of * this outgoing response. * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.3 */ public void testCachedEntityBodyIsUsedForResponseAfter304Validation() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("ETag","\"etag\""); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Cache-Control","max-age=0, max-stale=0"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); final InputStream i1 = resp1.getEntity().getContent(); final InputStream i2 = result.getEntity().getContent(); int b1, b2; while((b1 = i1.read()) != -1) { b2 = i2.read(); Assert.assertEquals(b1, b2); } b2 = i2.read(); Assert.assertEquals(-1, b2); i1.close(); i2.close(); } /* "The end-to-end headers stored in the cache entry are used for * the constructed response, except that ... * * - any end-to-end headers provided in the 304 or 206 response MUST * replace the corresponding headers from the cache entry. * * Unless the cache decides to remove the cache entry, it MUST * also replace the end-to-end headers stored with the cache entry * with corresponding headers received in the incoming response, * except for Warning headers as described immediately above." */ private void decorateWithEndToEndHeaders(final HttpResponse r) { r.setHeader("Allow","GET"); r.setHeader("Content-Encoding","gzip"); r.setHeader("Content-Language","en"); r.setHeader("Content-Length", "128"); r.setHeader("Content-Location","http://foo.example.com/other"); r.setHeader("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ=="); r.setHeader("Content-Type", "text/html;charset=utf-8"); r.setHeader("Expires", DateUtils.formatDate(new Date(System.currentTimeMillis() + 10 * 1000L))); r.setHeader("Last-Modified", DateUtils.formatDate(new Date(System.currentTimeMillis() - 10 * 1000L))); r.setHeader("Location", "http://foo.example.com/other2"); r.setHeader("Pragma", "x-pragma"); r.setHeader("Retry-After","180"); } @Test public void testResponseIncludesCacheEntryEndToEndHeadersForResponseAfter304Validation() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("ETag","\"etag\""); decorateWithEndToEndHeaders(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Cache-Control", "max-age=0, max-stale=0"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp2.setHeader("Date", DateUtils.formatDate(new Date())); resp2.setHeader("Server", "MockServer/1.0"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); final String[] endToEndHeaders = { "Cache-Control", "ETag", "Allow", "Content-Encoding", "Content-Language", "Content-Length", "Content-Location", "Content-MD5", "Content-Type", "Expires", "Last-Modified", "Location", "Pragma", "Retry-After" }; for(final String h : endToEndHeaders) { Assert.assertEquals(HttpTestUtils.getCanonicalHeaderValue(resp1, h), HttpTestUtils.getCanonicalHeaderValue(result, h)); } } @Test public void testUpdatedEndToEndHeadersFrom304ArePassedOnResponseAndUpdatedInCacheEntry() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("ETag","\"etag\""); decorateWithEndToEndHeaders(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Cache-Control", "max-age=0, max-stale=0"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp2.setHeader("Cache-Control", "max-age=1800"); resp2.setHeader("Date", DateUtils.formatDate(new Date())); resp2.setHeader("Server", "MockServer/1.0"); resp2.setHeader("Allow", "GET,HEAD"); resp2.setHeader("Content-Language", "en,en-us"); resp2.setHeader("Content-Location", "http://foo.example.com/new"); resp2.setHeader("Content-Type","text/html"); resp2.setHeader("Expires", DateUtils.formatDate(new Date(System.currentTimeMillis() + 5 * 1000L))); resp2.setHeader("Location", "http://foo.example.com/new2"); resp2.setHeader("Pragma","x-new-pragma"); resp2.setHeader("Retry-After","120"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result1 = impl.execute(route, req2, context, null); final HttpResponse result2 = impl.execute(route, req3, context, null); verifyMocks(); final String[] endToEndHeaders = { "Date", "Cache-Control", "Allow", "Content-Language", "Content-Location", "Content-Type", "Expires", "Location", "Pragma", "Retry-After" }; for(final String h : endToEndHeaders) { Assert.assertEquals(HttpTestUtils.getCanonicalHeaderValue(resp2, h), HttpTestUtils.getCanonicalHeaderValue(result1, h)); Assert.assertEquals(HttpTestUtils.getCanonicalHeaderValue(resp2, h), HttpTestUtils.getCanonicalHeaderValue(result2, h)); } } /* "If a header field-name in the incoming response matches more * than one header in the cache entry, all such old headers MUST * be replaced." */ @Test public void testMultiHeadersAreSuccessfullyReplacedOn304Validation() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.addHeader("Cache-Control","max-age=3600"); resp1.addHeader("Cache-Control","public"); resp1.setHeader("ETag","\"etag\""); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Cache-Control", "max-age=0, max-stale=0"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp2.setHeader("Cache-Control", "max-age=1800"); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result1 = impl.execute(route, req2, context, null); final HttpResponse result2 = impl.execute(route, req3, context, null); verifyMocks(); final String h = "Cache-Control"; Assert.assertEquals(HttpTestUtils.getCanonicalHeaderValue(resp2, h), HttpTestUtils.getCanonicalHeaderValue(result1, h)); Assert.assertEquals(HttpTestUtils.getCanonicalHeaderValue(resp2, h), HttpTestUtils.getCanonicalHeaderValue(result2, h)); } /* "If a cache has a stored non-empty set of subranges for an * entity, and an incoming response transfers another subrange, * the cache MAY combine the new subrange with the existing set if * both the following conditions are met: * * - Both the incoming response and the cache entry have a cache * validator. * * - The two cache validators match using the strong comparison * function (see section 13.3.3). * * If either requirement is not met, the cache MUST use only the * most recent partial response (based on the Date values * transmitted with every response, and using the incoming * response if these values are equal or missing), and MUST * discard the other partial information." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.4 */ @Test public void testCannotCombinePartialResponseIfIncomingResponseDoesNotHaveACacheValidator() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("Range","bytes=0-49"); final Date now = new Date(); final Date oneSecondAgo = new Date(now.getTime() - 1 * 1000L); final Date twoSecondsAgo = new Date(now.getTime() - 2 * 1000L); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Server","MockServer/1.0"); resp1.setHeader("Date", DateUtils.formatDate(twoSecondsAgo)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("ETag","\"etag1\""); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Range","bytes=50-127"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("Server","MockServer/1.0"); resp2.setHeader("Date", DateUtils.formatDate(oneSecondAgo)); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); backendExpectsAnyRequestAndReturn(resp3); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); impl.execute(route, req3, context, null); verifyMocks(); } @Test public void testCannotCombinePartialResponseIfCacheEntryDoesNotHaveACacheValidator() throws Exception { final Date now = new Date(); final Date oneSecondAgo = new Date(now.getTime() - 1 * 1000L); final Date twoSecondsAgo = new Date(now.getTime() - 2 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("Range","bytes=0-49"); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("Server","MockServer/1.0"); resp1.setHeader("Date", DateUtils.formatDate(twoSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Range","bytes=50-127"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("ETag","\"etag1\""); resp2.setHeader("Server","MockServer/1.0"); resp2.setHeader("Date", DateUtils.formatDate(oneSecondAgo)); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); backendExpectsAnyRequestAndReturn(resp3); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); impl.execute(route, req3, context, null); verifyMocks(); } @Test public void testCannotCombinePartialResponseIfCacheValidatorsDoNotStronglyMatch() throws Exception { final Date now = new Date(); final Date oneSecondAgo = new Date(now.getTime() - 1 * 1000L); final Date twoSecondsAgo = new Date(now.getTime() - 2 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("Range","bytes=0-49"); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("ETag","\"etag1\""); resp1.setHeader("Server","MockServer/1.0"); resp1.setHeader("Date", DateUtils.formatDate(twoSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Range","bytes=50-127"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("ETag","\"etag2\""); resp2.setHeader("Server","MockServer/1.0"); resp2.setHeader("Date", DateUtils.formatDate(oneSecondAgo)); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); backendExpectsAnyRequestAndReturn(resp3); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); impl.execute(route, req3, context, null); verifyMocks(); } @Test public void testMustDiscardLeastRecentPartialResponseIfIncomingRequestDoesNotHaveCacheValidator() throws Exception { final Date now = new Date(); final Date oneSecondAgo = new Date(now.getTime() - 1 * 1000L); final Date twoSecondsAgo = new Date(now.getTime() - 2 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("Range","bytes=0-49"); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("ETag","\"etag1\""); resp1.setHeader("Server","MockServer/1.0"); resp1.setHeader("Date", DateUtils.formatDate(twoSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Range","bytes=50-127"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("Server","MockServer/1.0"); resp2.setHeader("Date", DateUtils.formatDate(oneSecondAgo)); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req3.setHeader("Range","bytes=0-49"); final HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); // must make this request; cannot serve from cache backendExpectsAnyRequestAndReturn(resp3); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); impl.execute(route, req3, context, null); verifyMocks(); } @Test public void testMustDiscardLeastRecentPartialResponseIfCachedResponseDoesNotHaveCacheValidator() throws Exception { final Date now = new Date(); final Date oneSecondAgo = new Date(now.getTime() - 1 * 1000L); final Date twoSecondsAgo = new Date(now.getTime() - 2 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("Range","bytes=0-49"); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("Server","MockServer/1.0"); resp1.setHeader("Date", DateUtils.formatDate(twoSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Range","bytes=50-127"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("ETag","\"etag1\""); resp2.setHeader("Server","MockServer/1.0"); resp2.setHeader("Date", DateUtils.formatDate(oneSecondAgo)); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req3.setHeader("Range","bytes=0-49"); final HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); // must make this request; cannot serve from cache backendExpectsAnyRequestAndReturn(resp3); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); impl.execute(route, req3, context, null); verifyMocks(); } @Test public void testMustDiscardLeastRecentPartialResponseIfCacheValidatorsDoNotStronglyMatch() throws Exception { final Date now = new Date(); final Date oneSecondAgo = new Date(now.getTime() - 1 * 1000L); final Date twoSecondsAgo = new Date(now.getTime() - 2 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("Range","bytes=0-49"); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("Etag","\"etag1\""); resp1.setHeader("Server","MockServer/1.0"); resp1.setHeader("Date", DateUtils.formatDate(twoSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Range","bytes=50-127"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("ETag","\"etag2\""); resp2.setHeader("Server","MockServer/1.0"); resp2.setHeader("Date", DateUtils.formatDate(oneSecondAgo)); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req3.setHeader("Range","bytes=0-49"); final HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); // must make this request; cannot serve from cache backendExpectsAnyRequestAndReturn(resp3); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); impl.execute(route, req3, context, null); verifyMocks(); } @Test public void testMustDiscardLeastRecentPartialResponseIfCacheValidatorsDoNotStronglyMatchEvenIfResponsesOutOfOrder() throws Exception { final Date now = new Date(); final Date oneSecondAgo = new Date(now.getTime() - 1 * 1000L); final Date twoSecondsAgo = new Date(now.getTime() - 2 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("Range","bytes=0-49"); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("Etag","\"etag1\""); resp1.setHeader("Server","MockServer/1.0"); resp1.setHeader("Date", DateUtils.formatDate(oneSecondAgo)); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Range","bytes=50-127"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("ETag","\"etag2\""); resp2.setHeader("Server","MockServer/1.0"); resp2.setHeader("Date", DateUtils.formatDate(twoSecondsAgo)); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req3.setHeader("Range","bytes=50-127"); final HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); // must make this request; cannot serve from cache backendExpectsAnyRequestAndReturn(resp3); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); impl.execute(route, req3, context, null); verifyMocks(); } @Test public void testMustDiscardCachedPartialResponseIfCacheValidatorsDoNotStronglyMatchAndDateHeadersAreEqual() throws Exception { final Date now = new Date(); final Date oneSecondAgo = new Date(now.getTime() - 1 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("Range","bytes=0-49"); final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp1.setEntity(HttpTestUtils.makeBody(50)); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Content-Range","bytes 0-49/128"); resp1.setHeader("Etag","\"etag1\""); resp1.setHeader("Server","MockServer/1.0"); resp1.setHeader("Date", DateUtils.formatDate(oneSecondAgo)); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Range","bytes=50-127"); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); resp2.setEntity(HttpTestUtils.makeBody(78)); resp2.setHeader("Cache-Control","max-age=3600"); resp2.setHeader("Content-Range","bytes 50-127/128"); resp2.setHeader("ETag","\"etag2\""); resp2.setHeader("Server","MockServer/1.0"); resp2.setHeader("Date", DateUtils.formatDate(oneSecondAgo)); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req3.setHeader("Range","bytes=0-49"); final HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); resp3.setEntity(HttpTestUtils.makeBody(128)); resp3.setHeader("Server","MockServer/1.0"); resp3.setHeader("Date", DateUtils.formatDate(now)); // must make this request; cannot serve from cache backendExpectsAnyRequestAndReturn(resp3); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); impl.execute(route, req3, context, null); verifyMocks(); } /* "When the cache receives a subsequent request whose Request-URI * specifies one or more cache entries including a Vary header * field, the cache MUST NOT use such a cache entry to construct a * response to the new request unless all of the selecting * request-headers present in the new request match the * corresponding stored request-headers in the original request." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6 */ @Test public void testCannotUseVariantCacheEntryIfNotAllSelectingRequestHeadersMatch() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("Accept-Encoding","gzip"); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag","\"etag1\""); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Vary","Accept-Encoding"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.removeHeaders("Accept-Encoding"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag","\"etag1\""); resp2.setHeader("Cache-Control","max-age=3600"); // not allowed to have a cache hit; must forward request backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); } /* "A Vary header field-value of "*" always fails to match and * subsequent requests on that resource can only be properly * interpreted by the origin server." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6 */ @Test public void testCannotServeFromCacheForVaryStar() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag","\"etag1\""); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Vary","*"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag","\"etag1\""); resp2.setHeader("Cache-Control","max-age=3600"); // not allowed to have a cache hit; must forward request backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); } /* " If the selecting request header fields for the cached entry * do not match the selecting request header fields of the new * request, then the cache MUST NOT use a cached entry to satisfy * the request unless it first relays the new request to the * origin server in a conditional request and the server responds * with 304 (Not Modified), including an entity tag or * Content-Location that indicates the entity to be used. * * If an entity tag was assigned to a cached representation, the * forwarded request SHOULD be conditional and include the entity * tags in an If-None-Match header field from all its cache * entries for the resource. This conveys to the server the set of * entities currently held by the cache, so that if any one of * these entities matches the requested entity, the server can use * the ETag header field in its 304 (Not Modified) response to * tell the cache which entry is appropriate. If the entity-tag of * the new response matches that of an existing entry, the new * response SHOULD be used to update the header fields of the * existing entry, and the result MUST be returned to the client. * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6 */ @Test public void testNonmatchingVariantCannotBeServedFromCacheUnlessConditionallyValidated() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("User-Agent","MyBrowser/1.0"); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag","\"etag1\""); resp1.setHeader("Cache-Control","max-age=3600"); resp1.setHeader("Vary","User-Agent"); resp1.setHeader("Content-Type","application/octet-stream"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("User-Agent","MyBrowser/1.5"); final HttpRequestWrapper conditional = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); conditional.setHeader("User-Agent","MyBrowser/1.5"); conditional.setHeader("If-None-Match","\"etag1\""); final HttpResponse resp200 = HttpTestUtils.make200Response(); resp200.setHeader("ETag","\"etag1\""); resp200.setHeader("Vary","User-Agent"); final HttpResponse resp304 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp304.setHeader("ETag","\"etag1\""); resp304.setHeader("Vary","User-Agent"); final Capture condCap = new Capture(); final Capture uncondCap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.and(eqRequest(conditional), EasyMock.capture(condCap)), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp304)).times(0,1); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.and(eqRequest(req2), EasyMock.capture(uncondCap)), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp200)).times(0,1); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (HttpStatus.SC_OK == result.getStatusLine().getStatusCode()) { Assert.assertTrue(condCap.hasCaptured() || uncondCap.hasCaptured()); if (uncondCap.hasCaptured()) { Assert.assertTrue(HttpTestUtils.semanticallyTransparent(resp200, result)); } } } /* "A cache that receives an incomplete response (for example, * with fewer bytes of data than specified in a Content-Length * header) MAY store the response. However, the cache MUST treat * this as a partial response. Partial responses MAY be combined * as described in section 13.5.4; the result might be a full * response or might still be partial. A cache MUST NOT return a * partial response to a client without explicitly marking it as * such, using the 206 (Partial Content) status code. A cache MUST * NOT return a partial response using a status code of 200 (OK)." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.8 */ @Test public void testIncompleteResponseMustNotBeReturnedToClientWithoutMarkingItAs206() throws Exception { originResponse.setEntity(HttpTestUtils.makeBody(128)); originResponse.setHeader("Content-Length","256"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); final int status = result.getStatusLine().getStatusCode(); Assert.assertFalse(HttpStatus.SC_OK == status); if (status > 200 && status <= 299 && HttpTestUtils.equivalent(originResponse.getEntity(), result.getEntity())) { Assert.assertTrue(HttpStatus.SC_PARTIAL_CONTENT == status); } } /* "Some HTTP methods MUST cause a cache to invalidate an * entity. This is either the entity referred to by the * Request-URI, or by the Location or Content-Location headers (if * present). These methods are: * - PUT * - DELETE * - POST * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.9 */ protected void testUnsafeOperationInvalidatesCacheForThatUri( final HttpRequestWrapper unsafeReq) throws Exception, IOException { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","public, max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, "No Content"); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp3 = HttpTestUtils.make200Response(); resp3.setHeader("Cache-Control","public, max-age=3600"); // this origin request MUST happen due to invalidation backendExpectsAnyRequestAndReturn(resp3); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, unsafeReq, context, null); impl.execute(route, req3, context, null); verifyMocks(); } @Test public void testPutToUriInvalidatesCacheForThatUri() throws Exception { final HttpRequest req = makeRequestWithBody("PUT","/"); testUnsafeOperationInvalidatesCacheForThatUri(HttpRequestWrapper.wrap(req)); } @Test public void testDeleteToUriInvalidatesCacheForThatUri() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap(new BasicHttpRequest("DELETE","/")); testUnsafeOperationInvalidatesCacheForThatUri(req); } @Test public void testPostToUriInvalidatesCacheForThatUri() throws Exception { final HttpRequestWrapper req = makeRequestWithBody("POST","/"); testUnsafeOperationInvalidatesCacheForThatUri(req); } protected void testUnsafeMethodInvalidatesCacheForHeaderUri( final HttpRequestWrapper unsafeReq) throws Exception, IOException { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/content", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","public, max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, "No Content"); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/content", HttpVersion.HTTP_1_1)); final HttpResponse resp3 = HttpTestUtils.make200Response(); resp3.setHeader("Cache-Control","public, max-age=3600"); // this origin request MUST happen due to invalidation backendExpectsAnyRequestAndReturn(resp3); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, unsafeReq, context, null); impl.execute(route, req3, context, null); verifyMocks(); } protected void testUnsafeMethodInvalidatesCacheForUriInContentLocationHeader( final HttpRequestWrapper unsafeReq) throws Exception, IOException { unsafeReq.setHeader("Content-Location","http://foo.example.com/content"); testUnsafeMethodInvalidatesCacheForHeaderUri(unsafeReq); } protected void testUnsafeMethodInvalidatesCacheForRelativeUriInContentLocationHeader( final HttpRequestWrapper unsafeReq) throws Exception, IOException { unsafeReq.setHeader("Content-Location","/content"); testUnsafeMethodInvalidatesCacheForHeaderUri(unsafeReq); } protected void testUnsafeMethodInvalidatesCacheForUriInLocationHeader( final HttpRequestWrapper unsafeReq) throws Exception, IOException { unsafeReq.setHeader("Location","http://foo.example.com/content"); testUnsafeMethodInvalidatesCacheForHeaderUri(unsafeReq); } @Test public void testPutInvalidatesCacheForThatUriInContentLocationHeader() throws Exception { final HttpRequestWrapper req2 = makeRequestWithBody("PUT","/"); testUnsafeMethodInvalidatesCacheForUriInContentLocationHeader(req2); } @Test public void testPutInvalidatesCacheForThatUriInLocationHeader() throws Exception { final HttpRequestWrapper req = makeRequestWithBody("PUT","/"); testUnsafeMethodInvalidatesCacheForUriInLocationHeader(req); } @Test public void testPutInvalidatesCacheForThatUriInRelativeContentLocationHeader() throws Exception { final HttpRequestWrapper req = makeRequestWithBody("PUT","/"); testUnsafeMethodInvalidatesCacheForRelativeUriInContentLocationHeader(req); } @Test public void testDeleteInvalidatesCacheForThatUriInContentLocationHeader() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap(new BasicHttpRequest("DELETE", "/")); testUnsafeMethodInvalidatesCacheForUriInContentLocationHeader(req); } @Test public void testDeleteInvalidatesCacheForThatUriInRelativeContentLocationHeader() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap(new BasicHttpRequest("DELETE", "/")); testUnsafeMethodInvalidatesCacheForRelativeUriInContentLocationHeader(req); } @Test public void testDeleteInvalidatesCacheForThatUriInLocationHeader() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap(new BasicHttpRequest("DELETE", "/")); testUnsafeMethodInvalidatesCacheForUriInLocationHeader(req); } @Test public void testPostInvalidatesCacheForThatUriInContentLocationHeader() throws Exception { final HttpRequestWrapper req = makeRequestWithBody("POST","/"); testUnsafeMethodInvalidatesCacheForUriInContentLocationHeader(req); } @Test public void testPostInvalidatesCacheForThatUriInLocationHeader() throws Exception { final HttpRequestWrapper req = makeRequestWithBody("POST","/"); testUnsafeMethodInvalidatesCacheForUriInLocationHeader(req); } @Test public void testPostInvalidatesCacheForRelativeUriInContentLocationHeader() throws Exception { final HttpRequestWrapper req = makeRequestWithBody("POST","/"); testUnsafeMethodInvalidatesCacheForRelativeUriInContentLocationHeader(req); } /* "In order to prevent denial of service attacks, an invalidation based on the URI * in a Location or Content-Location header MUST only be performed if the host part * is the same as in the Request-URI." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.10 */ protected void testUnsafeMethodDoesNotInvalidateCacheForHeaderUri( final HttpRequestWrapper unsafeReq) throws Exception, IOException { final HttpHost otherHost = new HttpHost("bar.example.com"); final HttpRoute otherRoute = new HttpRoute(otherHost); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/content", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","public, max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, "No Content"); backendExpectsAnyRequestAndReturn(resp2); final HttpRequestWrapper req3 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/content", HttpVersion.HTTP_1_1)); replayMocks(); impl.execute(otherRoute, req1, context, null); impl.execute(route, unsafeReq, context, null); impl.execute(otherRoute, req3, context, null); verifyMocks(); } protected void testUnsafeMethodDoesNotInvalidateCacheForUriInContentLocationHeadersFromOtherHosts( final HttpRequestWrapper unsafeReq) throws Exception, IOException { unsafeReq.setHeader("Content-Location","http://bar.example.com/content"); testUnsafeMethodDoesNotInvalidateCacheForHeaderUri(unsafeReq); } protected void testUnsafeMethodDoesNotInvalidateCacheForUriInLocationHeadersFromOtherHosts( final HttpRequestWrapper unsafeReq) throws Exception, IOException { unsafeReq.setHeader("Location","http://bar.example.com/content"); testUnsafeMethodDoesNotInvalidateCacheForHeaderUri(unsafeReq); } protected HttpRequestWrapper makeRequestWithBody(final String method, final String requestUri) { final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(method, requestUri, HttpVersion.HTTP_1_1); final int nbytes = 128; request.setEntity(HttpTestUtils.makeBody(nbytes)); request.setHeader("Content-Length",""+nbytes); return HttpRequestWrapper.wrap(request); } @Test public void testPutDoesNotInvalidateCacheForUriInContentLocationHeadersFromOtherHosts() throws Exception { final HttpRequestWrapper req = makeRequestWithBody("PUT","/"); testUnsafeMethodDoesNotInvalidateCacheForUriInContentLocationHeadersFromOtherHosts(req); } @Test public void testPutDoesNotInvalidateCacheForUriInLocationHeadersFromOtherHosts() throws Exception { final HttpRequestWrapper req = makeRequestWithBody("PUT","/"); testUnsafeMethodDoesNotInvalidateCacheForUriInLocationHeadersFromOtherHosts(req); } @Test public void testPostDoesNotInvalidateCacheForUriInContentLocationHeadersFromOtherHosts() throws Exception { final HttpRequestWrapper req = makeRequestWithBody("POST","/"); testUnsafeMethodDoesNotInvalidateCacheForUriInContentLocationHeadersFromOtherHosts(req); } @Test public void testPostDoesNotInvalidateCacheForUriInLocationHeadersFromOtherHosts() throws Exception { final HttpRequestWrapper req = makeRequestWithBody("POST","/"); testUnsafeMethodDoesNotInvalidateCacheForUriInLocationHeadersFromOtherHosts(req); } @Test public void testDeleteDoesNotInvalidateCacheForUriInContentLocationHeadersFromOtherHosts() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap( new BasicHttpRequest("DELETE", "/", HttpVersion.HTTP_1_1)); testUnsafeMethodDoesNotInvalidateCacheForUriInContentLocationHeadersFromOtherHosts(req); } @Test public void testDeleteDoesNotInvalidateCacheForUriInLocationHeadersFromOtherHosts() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap( new BasicHttpRequest("DELETE", "/", HttpVersion.HTTP_1_1)); testUnsafeMethodDoesNotInvalidateCacheForUriInLocationHeadersFromOtherHosts(req); } /* "All methods that might be expected to cause modifications to the origin * server's resources MUST be written through to the origin server. This * currently includes all methods except for GET and HEAD. A cache MUST NOT * reply to such a request from a client before having transmitted the * request to the inbound server, and having received a corresponding * response from the inbound server." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.11 */ private void testRequestIsWrittenThroughToOrigin(final HttpRequest req) throws Exception { final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, "No Content"); final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(req); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), eqRequest(wrapper), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp)); replayMocks(); impl.execute(route, wrapper, context, null); verifyMocks(); } @Test @Ignore public void testOPTIONSRequestsAreWrittenThroughToOrigin() throws Exception { final HttpRequest req = HttpRequestWrapper.wrap( new BasicHttpRequest("OPTIONS","*",HttpVersion.HTTP_1_1)); testRequestIsWrittenThroughToOrigin(req); } @Test public void testPOSTRequestsAreWrittenThroughToOrigin() throws Exception { final HttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("POST","/",HttpVersion.HTTP_1_1); req.setEntity(HttpTestUtils.makeBody(128)); req.setHeader("Content-Length","128"); testRequestIsWrittenThroughToOrigin(req); } @Test public void testPUTRequestsAreWrittenThroughToOrigin() throws Exception { final HttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("PUT","/",HttpVersion.HTTP_1_1); req.setEntity(HttpTestUtils.makeBody(128)); req.setHeader("Content-Length","128"); testRequestIsWrittenThroughToOrigin(req); } @Test public void testDELETERequestsAreWrittenThroughToOrigin() throws Exception { final HttpRequest req = HttpRequestWrapper.wrap( new BasicHttpRequest("DELETE", "/", HttpVersion.HTTP_1_1)); testRequestIsWrittenThroughToOrigin(req); } @Test public void testTRACERequestsAreWrittenThroughToOrigin() throws Exception { final HttpRequest req = HttpRequestWrapper.wrap( new BasicHttpRequest("TRACE","/",HttpVersion.HTTP_1_1)); testRequestIsWrittenThroughToOrigin(req); } @Test public void testCONNECTRequestsAreWrittenThroughToOrigin() throws Exception { final HttpRequest req = HttpRequestWrapper.wrap( new BasicHttpRequest("CONNECT","/",HttpVersion.HTTP_1_1)); testRequestIsWrittenThroughToOrigin(req); } @Test public void testUnknownMethodRequestsAreWrittenThroughToOrigin() throws Exception { final HttpRequest req = HttpRequestWrapper.wrap( new BasicHttpRequest("UNKNOWN","/",HttpVersion.HTTP_1_1)); testRequestIsWrittenThroughToOrigin(req); } /* "If a cache receives a value larger than the largest positive * integer it can represent, or if any of its age calculations * overflows, it MUST transmit an Age header with a value of * 2147483648 (2^31)." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.6 */ @Test public void testTransmitsAgeHeaderIfIncomingAgeHeaderTooBig() throws Exception { final String reallyOldAge = "1" + Long.MAX_VALUE; originResponse.setHeader("Age",reallyOldAge); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertEquals("2147483648", result.getFirstHeader("Age").getValue()); } /* "A proxy MUST NOT modify the Allow header field even if it does not * understand all the methods specified, since the user agent might * have other means of communicating with the origin server. * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.7 */ @Test public void testDoesNotModifyAllowHeaderWithUnknownMethods() throws Exception { final String allowHeaderValue = "GET, HEAD, FOOBAR"; originResponse.setHeader("Allow",allowHeaderValue); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertEquals(HttpTestUtils.getCanonicalHeaderValue(originResponse,"Allow"), HttpTestUtils.getCanonicalHeaderValue(result, "Allow")); } /* "When a shared cache (see section 13.7) receives a request * containing an Authorization field, it MUST NOT return the * corresponding response as a reply to any other request, unless one * of the following specific exceptions holds: * * 1. If the response includes the "s-maxage" cache-control * directive, the cache MAY use that response in replying to a * subsequent request. But (if the specified maximum age has * passed) a proxy cache MUST first revalidate it with the origin * server, using the request-headers from the new request to allow * the origin server to authenticate the new request. (This is the * defined behavior for s-maxage.) If the response includes "s- * maxage=0", the proxy MUST always revalidate it before re-using * it. * * 2. If the response includes the "must-revalidate" cache-control * directive, the cache MAY use that response in replying to a * subsequent request. But if the response is stale, all caches * MUST first revalidate it with the origin server, using the * request-headers from the new request to allow the origin server * to authenticate the new request. * * 3. If the response includes the "public" cache-control directive, * it MAY be returned in reply to any subsequent request. */ protected void testSharedCacheRevalidatesAuthorizedResponse( final HttpResponse authorizedResponse, final int minTimes, final int maxTimes) throws Exception, IOException { if (config.isSharedCache()) { final String authorization = "Basic dXNlcjpwYXNzd2Q="; final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("Authorization",authorization); backendExpectsAnyRequestAndReturn(authorizedResponse); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Cache-Control","max-age=3600"); if (maxTimes > 0) { // this request MUST happen backendExpectsAnyRequest().andReturn( Proxies.enhanceResponse(resp2)).times(minTimes,maxTimes); } replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); } } @Test public void testSharedCacheMustNotNormallyCacheAuthorizedResponses() throws Exception { final HttpResponse resp = HttpTestUtils.make200Response(); resp.setHeader("Cache-Control","max-age=3600"); resp.setHeader("ETag","\"etag\""); testSharedCacheRevalidatesAuthorizedResponse(resp, 1, 1); } @Test public void testSharedCacheMayCacheAuthorizedResponsesWithSMaxAgeHeader() throws Exception { final HttpResponse resp = HttpTestUtils.make200Response(); resp.setHeader("Cache-Control","s-maxage=3600"); resp.setHeader("ETag","\"etag\""); testSharedCacheRevalidatesAuthorizedResponse(resp, 0, 1); } @Test public void testSharedCacheMustRevalidateAuthorizedResponsesWhenSMaxAgeIsZero() throws Exception { final HttpResponse resp = HttpTestUtils.make200Response(); resp.setHeader("Cache-Control","s-maxage=0"); resp.setHeader("ETag","\"etag\""); testSharedCacheRevalidatesAuthorizedResponse(resp, 1, 1); } @Test public void testSharedCacheMayCacheAuthorizedResponsesWithMustRevalidate() throws Exception { final HttpResponse resp = HttpTestUtils.make200Response(); resp.setHeader("Cache-Control","must-revalidate"); resp.setHeader("ETag","\"etag\""); testSharedCacheRevalidatesAuthorizedResponse(resp, 0, 1); } @Test public void testSharedCacheMayCacheAuthorizedResponsesWithCacheControlPublic() throws Exception { final HttpResponse resp = HttpTestUtils.make200Response(); resp.setHeader("Cache-Control","public"); testSharedCacheRevalidatesAuthorizedResponse(resp, 0, 1); } protected void testSharedCacheMustUseNewRequestHeadersWhenRevalidatingAuthorizedResponse( final HttpResponse authorizedResponse) throws Exception, IOException, ClientProtocolException { if (config.isSharedCache()) { final String authorization1 = "Basic dXNlcjpwYXNzd2Q="; final String authorization2 = "Basic dXNlcjpwYXNzd2Qy"; final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req1.setHeader("Authorization",authorization1); backendExpectsAnyRequestAndReturn(authorizedResponse); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Authorization",authorization2); final HttpResponse resp2 = HttpTestUtils.make200Response(); final Capture cap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); final HttpRequest captured = cap.getValue(); Assert.assertEquals(HttpTestUtils.getCanonicalHeaderValue(req2, "Authorization"), HttpTestUtils.getCanonicalHeaderValue(captured, "Authorization")); } } @Test public void testSharedCacheMustUseNewRequestHeadersWhenRevalidatingAuthorizedResponsesWithSMaxAge() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date",DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Cache-Control","s-maxage=5"); testSharedCacheMustUseNewRequestHeadersWhenRevalidatingAuthorizedResponse(resp1); } @Test public void testSharedCacheMustUseNewRequestHeadersWhenRevalidatingAuthorizedResponsesWithMustRevalidate() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date",DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Cache-Control","maxage=5, must-revalidate"); testSharedCacheMustUseNewRequestHeadersWhenRevalidatingAuthorizedResponse(resp1); } /* "If a cache returns a stale response, either because of a max-stale * directive on a request, or because the cache is configured to * override the expiration time of a response, the cache MUST attach a * Warning header to the stale response, using Warning 110 (Response * is stale). * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3 * * "110 Response is stale MUST be included whenever the returned * response is stale." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.46 */ @Test public void testWarning110IsAddedToStaleResponses() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control","max-age=5"); resp1.setHeader("Etag","\"etag\""); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Cache-Control","max-stale=60"); final HttpResponse resp2 = HttpTestUtils.make200Response(); final Capture cap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)).times(0,1); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (!cap.hasCaptured()) { boolean found110Warning = false; for(final Header h : result.getHeaders("Warning")) { for(final HeaderElement elt : h.getElements()) { final String[] parts = elt.getName().split("\\s"); if ("110".equals(parts[0])) { found110Warning = true; break; } } } Assert.assertTrue(found110Warning); } } /* "Field names MUST NOT be included with the no-cache directive in a * request." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 */ @Test public void testDoesNotTransmitNoCacheDirectivesWithFieldsDownstream() throws Exception { request.setHeader("Cache-Control","no-cache=\"X-Field\""); final Capture cap = new Capture(); EasyMock.expect(mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse).times(0,1); replayMocks(); try { impl.execute(route, request, context, null); } catch (final ClientProtocolException acceptable) { } verifyMocks(); if (cap.hasCaptured()) { final HttpRequest captured = cap.getValue(); for(final Header h : captured.getHeaders("Cache-Control")) { for(final HeaderElement elt : h.getElements()) { if ("no-cache".equals(elt.getName())) { Assert.assertNull(elt.getValue()); } } } } } /* "The request includes a "no-cache" cache-control directive or, for * compatibility with HTTP/1.0 clients, "Pragma: no-cache".... The * server MUST NOT use a cached copy when responding to such a request." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 */ protected void testCacheIsNotUsedWhenRespondingToRequest(final HttpRequestWrapper req) throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Etag","\"etag\""); resp1.setHeader("Cache-Control","max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Etag","\"etag2\""); resp2.setHeader("Cache-Control","max-age=1200"); final Capture cap = new Capture(); EasyMock.expect(mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req, context, null); verifyMocks(); Assert.assertTrue(HttpTestUtils.semanticallyTransparent(resp2, result)); final HttpRequest captured = cap.getValue(); Assert.assertTrue(HttpTestUtils.equivalent(req, captured)); } @Test public void testCacheIsNotUsedWhenRespondingToRequestWithCacheControlNoCache() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req.setHeader("Cache-Control","no-cache"); testCacheIsNotUsedWhenRespondingToRequest(req); } @Test public void testCacheIsNotUsedWhenRespondingToRequestWithPragmaNoCache() throws Exception { final HttpRequestWrapper req = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req.setHeader("Pragma","no-cache"); testCacheIsNotUsedWhenRespondingToRequest(req); } /* "When the must-revalidate directive is present in a response received * by a cache, that cache MUST NOT use the entry after it becomes stale * to respond to a subsequent request without first revalidating it with * the origin server. (I.e., the cache MUST do an end-to-end * revalidation every time, if, based solely on the origin server's * Expires or max-age value, the cached response is stale.)" * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 */ protected void testStaleCacheResponseMustBeRevalidatedWithOrigin( final HttpResponse staleResponse) throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); backendExpectsAnyRequestAndReturn(staleResponse); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Cache-Control","max-stale=3600"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag","\"etag2\""); resp2.setHeader("Cache-Control","max-age=5, must-revalidate"); final Capture cap = new Capture(); // this request MUST happen EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); final HttpRequest reval = cap.getValue(); boolean foundMaxAge0 = false; for(final Header h : reval.getHeaders("Cache-Control")) { for(final HeaderElement elt : h.getElements()) { if ("max-age".equalsIgnoreCase(elt.getName()) && "0".equals(elt.getValue())) { foundMaxAge0 = true; } } } Assert.assertTrue(foundMaxAge0); } @Test public void testStaleEntryWithMustRevalidateIsNotUsedWithoutRevalidatingWithOrigin() throws Exception { final HttpResponse response = HttpTestUtils.make200Response(); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); response.setHeader("Date",DateUtils.formatDate(tenSecondsAgo)); response.setHeader("ETag","\"etag1\""); response.setHeader("Cache-Control","max-age=5, must-revalidate"); testStaleCacheResponseMustBeRevalidatedWithOrigin(response); } /* "In all circumstances an HTTP/1.1 cache MUST obey the must-revalidate * directive; in particular, if the cache cannot reach the origin server * for any reason, it MUST generate a 504 (Gateway Timeout) response." */ protected void testGenerates504IfCannotRevalidateStaleResponse( final HttpResponse staleResponse) throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); backendExpectsAnyRequestAndReturn(staleResponse); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); backendExpectsAnyRequest().andThrow(new SocketTimeoutException()); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT, result.getStatusLine().getStatusCode()); } @Test public void testGenerates504IfCannotRevalidateAMustRevalidateEntry() throws Exception { final HttpResponse resp1 = HttpTestUtils.make200Response(); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control","max-age=5,must-revalidate"); testGenerates504IfCannotRevalidateStaleResponse(resp1); } /* "The proxy-revalidate directive has the same meaning as the must- * revalidate directive, except that it does not apply to non-shared * user agent caches." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 */ @Test public void testStaleEntryWithProxyRevalidateOnSharedCacheIsNotUsedWithoutRevalidatingWithOrigin() throws Exception { if (config.isSharedCache()) { final HttpResponse response = HttpTestUtils.make200Response(); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); response.setHeader("Date",DateUtils.formatDate(tenSecondsAgo)); response.setHeader("ETag","\"etag1\""); response.setHeader("Cache-Control","max-age=5, proxy-revalidate"); testStaleCacheResponseMustBeRevalidatedWithOrigin(response); } } @Test public void testGenerates504IfSharedCacheCannotRevalidateAProxyRevalidateEntry() throws Exception { if (config.isSharedCache()) { final HttpResponse resp1 = HttpTestUtils.make200Response(); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control","max-age=5,proxy-revalidate"); testGenerates504IfCannotRevalidateStaleResponse(resp1); } } /* "[The cache control directive] "private" Indicates that all or part of * the response message is intended for a single user and MUST NOT be * cached by a shared cache." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1 */ @Test public void testCacheControlPrivateIsNotCacheableBySharedCache() throws Exception { if (config.isSharedCache()) { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","private,max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = HttpTestUtils.make200Response(); // this backend request MUST happen backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); } } @Test public void testCacheControlPrivateOnFieldIsNotReturnedBySharedCache() throws Exception { if (config.isSharedCache()) { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("X-Personal","stuff"); resp1.setHeader("Cache-Control","private=\"X-Personal\",s-maxage=3600"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = HttpTestUtils.make200Response(); // this backend request MAY happen backendExpectsAnyRequestAndReturn(resp2).times(0,1); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); Assert.assertNull(result.getFirstHeader("X-Personal")); } } /* "If the no-cache directive does not specify a field-name, then a * cache MUST NOT use the response to satisfy a subsequent request * without successful revalidation with the origin server. This allows * an origin server to prevent caching even by caches that have been * configured to return stale responses to client requests." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1 */ @Test public void testNoCacheCannotSatisfyASubsequentRequestWithoutRevalidation() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Cache-Control","no-cache"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = HttpTestUtils.make200Response(); // this MUST happen backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); } @Test public void testNoCacheCannotSatisfyASubsequentRequestWithoutRevalidationEvenWithContraryIndications() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Cache-Control","no-cache,s-maxage=3600"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Cache-Control","max-stale=7200"); final HttpResponse resp2 = HttpTestUtils.make200Response(); // this MUST happen backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); } /* "If the no-cache directive does specify one or more field-names, then * a cache MAY use the response to satisfy a subsequent request, subject * to any other restrictions on caching. However, the specified * field-name(s) MUST NOT be sent in the response to a subsequent request * without successful revalidation with the origin server." */ @Test public void testNoCacheOnFieldIsNotReturnedWithoutRevalidation() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("X-Stuff","things"); resp1.setHeader("Cache-Control","no-cache=\"X-Stuff\", max-age=3600"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("ETag","\"etag\""); resp2.setHeader("X-Stuff","things"); resp2.setHeader("Cache-Control","no-cache=\"X-Stuff\",max-age=3600"); final Capture cap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.eq(route), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn( Proxies.enhanceResponse(resp2)).times(0,1); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); if (!cap.hasCaptured()) { Assert.assertNull(result.getFirstHeader("X-Stuff")); } } /* "The purpose of the no-store directive is to prevent the inadvertent * release or retention of sensitive information (for example, on backup * tapes). The no-store directive applies to the entire message, and MAY * be sent either in a response or in a request. If sent in a request, a * cache MUST NOT store any part of either this request or any response * to it. If sent in a response, a cache MUST NOT store any part of * either this response or the request that elicited it. This directive * applies to both non- shared and shared caches. "MUST NOT store" in * this context means that the cache MUST NOT intentionally store the * information in non-volatile storage, and MUST make a best-effort * attempt to remove the information from volatile storage as promptly * as possible after forwarding it." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.2 */ @Test public void testNoStoreOnRequestIsNotStoredInCache() throws Exception { emptyMockCacheExpectsNoPuts(); request.setHeader("Cache-Control","no-store"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); } @Test public void testNoStoreOnRequestIsNotStoredInCacheEvenIfResponseMarkedCacheable() throws Exception { emptyMockCacheExpectsNoPuts(); request.setHeader("Cache-Control","no-store"); originResponse.setHeader("Cache-Control","max-age=3600"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); } @Test public void testNoStoreOnResponseIsNotStoredInCache() throws Exception { emptyMockCacheExpectsNoPuts(); originResponse.setHeader("Cache-Control","no-store"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); } @Test public void testNoStoreOnResponseIsNotStoredInCacheEvenWithContraryIndicators() throws Exception { emptyMockCacheExpectsNoPuts(); originResponse.setHeader("Cache-Control","no-store,max-age=3600"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); } /* "If multiple encodings have been applied to an entity, the content * codings MUST be listed in the order in which they were applied." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11 */ @Test public void testOrderOfMultipleContentEncodingHeaderValuesIsPreserved() throws Exception { originResponse.addHeader("Content-Encoding","gzip"); originResponse.addHeader("Content-Encoding","deflate"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); int total_encodings = 0; for(final Header hdr : result.getHeaders("Content-Encoding")) { for(final HeaderElement elt : hdr.getElements()) { switch(total_encodings) { case 0: Assert.assertEquals("gzip", elt.getName()); break; case 1: Assert.assertEquals("deflate", elt.getName()); break; default: Assert.fail("too many encodings"); } total_encodings++; } } Assert.assertEquals(2, total_encodings); } @Test public void testOrderOfMultipleParametersInContentEncodingHeaderIsPreserved() throws Exception { originResponse.addHeader("Content-Encoding","gzip,deflate"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); int total_encodings = 0; for(final Header hdr : result.getHeaders("Content-Encoding")) { for(final HeaderElement elt : hdr.getElements()) { switch(total_encodings) { case 0: Assert.assertEquals("gzip", elt.getName()); break; case 1: Assert.assertEquals("deflate", elt.getName()); break; default: Assert.fail("too many encodings"); } total_encodings++; } } Assert.assertEquals(2, total_encodings); } /* "A cache cannot assume that an entity with a Content-Location * different from the URI used to retrieve it can be used to respond * to later requests on that Content-Location URI." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.14 */ @Test public void testCacheDoesNotAssumeContentLocationHeaderIndicatesAnotherCacheableResource() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","public,max-age=3600"); resp1.setHeader("Etag","\"etag\""); resp1.setHeader("Content-Location","http://foo.example.com/bar"); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/bar", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Cache-Control","public,max-age=3600"); resp2.setHeader("Etag","\"etag\""); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); } /* "A received message that does not have a Date header field MUST be * assigned one by the recipient if the message will be cached by that * recipient or gatewayed via a protocol which requires a Date." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.18 */ @Test public void testCachedResponsesWithMissingDateHeadersShouldBeAssignedOne() throws Exception { originResponse.removeHeaders("Date"); originResponse.setHeader("Cache-Control","public"); originResponse.setHeader("ETag","\"etag\""); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertNotNull(result.getFirstHeader("Date")); } /* "The Expires entity-header field gives the date/time after which the * response is considered stale.... HTTP/1.1 clients and caches MUST * treat other invalid date formats, especially including the value '0', * as in the past (i.e., 'already expired')." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21 */ private void testInvalidExpiresHeaderIsTreatedAsStale( final String expiresHeader) throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","public"); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Expires", expiresHeader); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = HttpTestUtils.make200Response(); backendExpectsAnyRequestAndReturn(resp1); // second request to origin MUST happen backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); } @Test public void testMalformedExpiresHeaderIsTreatedAsStale() throws Exception { testInvalidExpiresHeaderIsTreatedAsStale("garbage"); } @Test public void testExpiresZeroHeaderIsTreatedAsStale() throws Exception { testInvalidExpiresHeaderIsTreatedAsStale("0"); } /* "To mark a response as 'already expired,' an origin server sends * an Expires date that is equal to the Date header value." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21 */ @Test public void testExpiresHeaderEqualToDateHeaderIsTreatedAsStale() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control","public"); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Expires", resp1.getFirstHeader("Date").getValue()); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = HttpTestUtils.make200Response(); backendExpectsAnyRequestAndReturn(resp1); // second request to origin MUST happen backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); } /* "If the response is being forwarded through a proxy, the proxy * application MUST NOT modify the Server response-header." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.38 */ @Test public void testDoesNotModifyServerResponseHeader() throws Exception { final String server = "MockServer/1.0"; originResponse.setHeader("Server", server); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertEquals(server, result.getFirstHeader("Server").getValue()); } /* "If multiple encodings have been applied to an entity, the transfer- * codings MUST be listed in the order in which they were applied." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.41 */ @Test public void testOrderOfMultipleTransferEncodingHeadersIsPreserved() throws Exception { originResponse.addHeader("Transfer-Encoding","chunked"); originResponse.addHeader("Transfer-Encoding","x-transfer"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); int transfer_encodings = 0; for(final Header h : result.getHeaders("Transfer-Encoding")) { for(final HeaderElement elt : h.getElements()) { switch(transfer_encodings) { case 0: Assert.assertEquals("chunked",elt.getName()); break; case 1: Assert.assertEquals("x-transfer",elt.getName()); break; default: Assert.fail("too many transfer encodings"); } transfer_encodings++; } } Assert.assertEquals(2, transfer_encodings); } @Test public void testOrderOfMultipleTransferEncodingsInSingleHeadersIsPreserved() throws Exception { originResponse.addHeader("Transfer-Encoding","chunked, x-transfer"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); int transfer_encodings = 0; for(final Header h : result.getHeaders("Transfer-Encoding")) { for(final HeaderElement elt : h.getElements()) { switch(transfer_encodings) { case 0: Assert.assertEquals("chunked",elt.getName()); break; case 1: Assert.assertEquals("x-transfer",elt.getName()); break; default: Assert.fail("too many transfer encodings"); } transfer_encodings++; } } Assert.assertEquals(2, transfer_encodings); } /* "A Vary field value of '*' signals that unspecified parameters * not limited to the request-headers (e.g., the network address * of the client), play a role in the selection of the response * representation. The '*' value MUST NOT be generated by a proxy * server; it may only be generated by an origin server." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44 */ @Test public void testVaryStarIsNotGeneratedByProxy() throws Exception { request.setHeader("User-Agent","my-agent/1.0"); originResponse.setHeader("Cache-Control","public, max-age=3600"); originResponse.setHeader("Vary","User-Agent"); originResponse.setHeader("ETag","\"etag\""); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); for(final Header h : result.getHeaders("Vary")) { for(final HeaderElement elt : h.getElements()) { Assert.assertFalse("*".equals(elt.getName())); } } } /* "The Via general-header field MUST be used by gateways and proxies * to indicate the intermediate protocols and recipients between the * user agent and the server on requests, and between the origin server * and the client on responses." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.45 */ @Test public void testProperlyFormattedViaHeaderIsAddedToRequests() throws Exception { final Capture cap = new Capture(); request.removeHeaders("Via"); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); final HttpRequest captured = cap.getValue(); final String via = captured.getFirstHeader("Via").getValue(); assertValidViaHeader(via); } @Test public void testProperlyFormattedViaHeaderIsAddedToResponses() throws Exception { originResponse.removeHeaders("Via"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); assertValidViaHeader(result.getFirstHeader("Via").getValue()); } private void assertValidViaHeader(final String via) { // Via = "Via" ":" 1#( received-protocol received-by [ comment ] ) // received-protocol = [ protocol-name "/" ] protocol-version // protocol-name = token // protocol-version = token // received-by = ( host [ ":" port ] ) | pseudonym // pseudonym = token final String[] parts = via.split("\\s+"); Assert.assertTrue(parts.length >= 2); // received protocol final String receivedProtocol = parts[0]; final String[] protocolParts = receivedProtocol.split("/"); Assert.assertTrue(protocolParts.length >= 1); Assert.assertTrue(protocolParts.length <= 2); final String tokenRegexp = "[^\\p{Cntrl}()<>@,;:\\\\\"/\\[\\]?={} \\t]+"; for(final String protocolPart : protocolParts) { Assert.assertTrue(Pattern.matches(tokenRegexp, protocolPart)); } // received-by if (!Pattern.matches(tokenRegexp, parts[1])) { // host : port new HttpHost(parts[1]); } // comment if (parts.length > 2) { final StringBuilder buf = new StringBuilder(parts[2]); for(int i=3; i cap = new Capture(); EasyMock.expect( mockBackend.execute( EasyMock.isA(HttpRoute.class), EasyMock.capture(cap), EasyMock.isA(HttpClientContext.class), EasyMock.isNull())).andReturn(originResponse); replayMocks(); impl.execute(route, request, context, null); verifyMocks(); final HttpRequest captured = cap.getValue(); final String via = captured.getFirstHeader("Via").getValue(); final String protocol = via.split("\\s+")[0]; final String[] protoParts = protocol.split("/"); if (protoParts.length > 1) { Assert.assertTrue("http".equalsIgnoreCase(protoParts[0])); } Assert.assertEquals("1.0",protoParts[protoParts.length-1]); } @Test public void testViaHeaderOnResponseProperlyRecordsOriginProtocol() throws Exception { originResponse = Proxies.enhanceResponse( new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_NO_CONTENT, "No Content")); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); final String via = result.getFirstHeader("Via").getValue(); final String protocol = via.split("\\s+")[0]; final String[] protoParts = protocol.split("/"); Assert.assertTrue(protoParts.length >= 1); Assert.assertTrue(protoParts.length <= 2); if (protoParts.length > 1) { Assert.assertTrue("http".equalsIgnoreCase(protoParts[0])); } Assert.assertEquals("1.0", protoParts[protoParts.length - 1]); } /* "A cache MUST NOT delete any Warning header that it received with * a message." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.46 */ @Test public void testRetainsWarningHeadersReceivedFromUpstream() throws Exception { originResponse.removeHeaders("Warning"); final String warning = "199 fred \"misc\""; originResponse.addHeader("Warning", warning); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); Assert.assertEquals(warning, result.getFirstHeader("Warning").getValue()); } /* "However, if a cache successfully validates a cache entry, it * SHOULD remove any Warning headers previously attached to that * entry except as specified for specific Warning codes. It MUST * then add any Warning headers received in the validating response." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.46 */ @Test public void testUpdatesWarningHeadersOnValidation() throws Exception { final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final Date now = new Date(); final Date twentySecondsAgo = new Date(now.getTime() - 20 * 1000L); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(twentySecondsAgo)); resp1.setHeader("Cache-Control","public,max-age=5"); resp1.setHeader("ETag", "\"etag1\""); final String oldWarning = "113 wilma \"stale\""; resp1.setHeader("Warning", oldWarning); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified"); resp2.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp2.setHeader("ETag", "\"etag1\""); final String newWarning = "113 betty \"stale too\""; resp2.setHeader("Warning", newWarning); backendExpectsAnyRequestAndReturn(resp1); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); boolean oldWarningFound = false; boolean newWarningFound = false; for(final Header h : result.getHeaders("Warning")) { for(final String warnValue : h.getValue().split("\\s*,\\s*")) { if (oldWarning.equals(warnValue)) { oldWarningFound = true; } else if (newWarning.equals(warnValue)) { newWarningFound = true; } } } Assert.assertFalse(oldWarningFound); Assert.assertTrue(newWarningFound); } /* "If an implementation sends a message with one or more Warning * headers whose version is HTTP/1.0 or lower, then the sender MUST * include in each warning-value a warn-date that matches the date * in the response." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.46 */ @Test public void testWarnDatesAreAddedToWarningsOnLowerProtocolVersions() throws Exception { final String dateHdr = DateUtils.formatDate(new Date()); final String origWarning = "110 fred \"stale\""; originResponse.setStatusLine(HttpVersion.HTTP_1_0, HttpStatus.SC_OK); originResponse.addHeader("Warning", origWarning); originResponse.setHeader("Date", dateHdr); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); // note that currently the implementation acts as an HTTP/1.1 proxy, // which means that all the responses from the caching module should // be HTTP/1.1, so we won't actually be testing anything here until // that changes. if (HttpVersion.HTTP_1_0.greaterEquals(result.getProtocolVersion())) { Assert.assertEquals(dateHdr, result.getFirstHeader("Date").getValue()); boolean warningFound = false; final String targetWarning = origWarning + " \"" + dateHdr + "\""; for(final Header h : result.getHeaders("Warning")) { for(final String warning : h.getValue().split("\\s*,\\s*")) { if (targetWarning.equals(warning)) { warningFound = true; break; } } } Assert.assertTrue(warningFound); } } /* "If an implementation receives a message with a warning-value that * includes a warn-date, and that warn-date is different from the Date * value in the response, then that warning-value MUST be deleted from * the message before storing, forwarding, or using it. (This prevents * bad consequences of naive caching of Warning header fields.) If all * of the warning-values are deleted for this reason, the Warning * header MUST be deleted as well." * * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.46 */ @Test public void testStripsBadlyDatedWarningsFromForwardedResponses() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); originResponse.setHeader("Date", DateUtils.formatDate(now)); originResponse.addHeader("Warning", "110 fred \"stale\", 110 wilma \"stale\" \"" + DateUtils.formatDate(tenSecondsAgo) + "\""); originResponse.setHeader("Cache-Control","no-cache,no-store"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); for(final Header h : result.getHeaders("Warning")) { Assert.assertFalse(h.getValue().contains("wilma")); } } @Test public void testStripsBadlyDatedWarningsFromStoredResponses() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); originResponse.setHeader("Date", DateUtils.formatDate(now)); originResponse.addHeader("Warning", "110 fred \"stale\", 110 wilma \"stale\" \"" + DateUtils.formatDate(tenSecondsAgo) + "\""); originResponse.setHeader("Cache-Control","public,max-age=3600"); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); for(final Header h : result.getHeaders("Warning")) { Assert.assertFalse(h.getValue().contains("wilma")); } } @Test public void testRemovesWarningHeaderIfAllWarnValuesAreBadlyDated() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); originResponse.setHeader("Date", DateUtils.formatDate(now)); originResponse.addHeader("Warning", "110 wilma \"stale\" \"" + DateUtils.formatDate(tenSecondsAgo) + "\""); backendExpectsAnyRequest().andReturn(originResponse); replayMocks(); final HttpResponse result = impl.execute(route, request, context, null); verifyMocks(); final Header[] warningHeaders = result.getHeaders("Warning"); Assert.assertTrue(warningHeaders == null || warningHeaders.length == 0); } } ././@LongLink0100644 0000000 0000000 00000000200 12302131606 011615 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestRequestProtocolCompliance.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestReq0100644 0000000 0000000 00000015021 12301751715 032303 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.Arrays; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.HttpVersion; import org.apache.http.ProtocolVersion; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.message.BasicHttpEntityEnclosingRequest; import org.apache.http.message.BasicHttpRequest; import org.junit.Before; import org.junit.Test; public class TestRequestProtocolCompliance { private RequestProtocolCompliance impl; private HttpRequest req; @Before public void setUp() { req = HttpTestUtils.makeDefaultRequest(); impl = new RequestProtocolCompliance(false); } @Test public void testRequestWithWeakETagAndRange() throws Exception { req.setHeader("Range", "bytes=0-499"); req.setHeader("If-Range", "W/\"weak\""); assertEquals(1, impl.requestIsFatallyNonCompliant(req).size()); } @Test public void testRequestWithWeekETagForPUTOrDELETEIfMatch() throws Exception { req = new HttpPut("http://example.com/"); req.setHeader("If-Match", "W/\"weak\""); assertEquals(1, impl.requestIsFatallyNonCompliant(req).size()); } @Test public void testRequestWithWeekETagForPUTOrDELETEIfMatchAllowed() throws Exception { req = new HttpPut("http://example.com/"); req.setHeader("If-Match", "W/\"weak\""); impl = new RequestProtocolCompliance(true); assertEquals(Arrays.asList(), impl.requestIsFatallyNonCompliant(req)); } @Test public void testRequestContainsNoCacheDirectiveWithFieldName() throws Exception { req.setHeader("Cache-Control", "no-cache=false"); assertEquals(1, impl.requestIsFatallyNonCompliant(req).size()); } @Test public void doesNotModifyACompliantRequest() throws Exception { final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(req); impl.makeRequestCompliant(wrapper); assertTrue(HttpTestUtils.equivalent(req, wrapper)); } @Test public void removesEntityFromTRACERequest() throws Exception { final HttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("TRACE", "/", HttpVersion.HTTP_1_1); req.setEntity(HttpTestUtils.makeBody(50)); final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(req); impl.makeRequestCompliant(wrapper); if (wrapper instanceof HttpEntityEnclosingRequest) { assertNull(((HttpEntityEnclosingRequest) wrapper).getEntity()); } } @Test public void upgrades1_0RequestTo1_1() throws Exception { req = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_0); final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(req); impl.makeRequestCompliant(wrapper); assertEquals(HttpVersion.HTTP_1_1, wrapper.getProtocolVersion()); } @Test public void downgrades1_2RequestTo1_1() throws Exception { final ProtocolVersion HTTP_1_2 = new ProtocolVersion("HTTP", 1, 2); req = new BasicHttpRequest("GET", "/", HTTP_1_2); final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(req); impl.makeRequestCompliant(wrapper); assertEquals(HttpVersion.HTTP_1_1, wrapper.getProtocolVersion()); } @Test public void stripsMinFreshFromRequestIfNoCachePresent() throws Exception { req.setHeader("Cache-Control", "no-cache, min-fresh=10"); final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(req); impl.makeRequestCompliant(wrapper); assertEquals("no-cache", wrapper.getFirstHeader("Cache-Control").getValue()); } @Test public void stripsMaxFreshFromRequestIfNoCachePresent() throws Exception { req.setHeader("Cache-Control", "no-cache, max-stale=10"); final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(req); impl.makeRequestCompliant(wrapper); assertEquals("no-cache", wrapper.getFirstHeader("Cache-Control").getValue()); } @Test public void stripsMaxAgeFromRequestIfNoCachePresent() throws Exception { req.setHeader("Cache-Control", "no-cache, max-age=10"); final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(req); impl.makeRequestCompliant(wrapper); assertEquals("no-cache", wrapper.getFirstHeader("Cache-Control").getValue()); } @Test public void doesNotStripMinFreshFromRequestWithoutNoCache() throws Exception { req.setHeader("Cache-Control", "min-fresh=10"); final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(req); impl.makeRequestCompliant(wrapper); assertEquals("min-fresh=10", wrapper.getFirstHeader("Cache-Control").getValue()); } @Test public void correctlyStripsMinFreshFromMiddleIfNoCache() throws Exception { req.setHeader("Cache-Control", "no-cache,min-fresh=10,no-store"); final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(req); impl.makeRequestCompliant(wrapper); assertEquals("no-cache,no-store", wrapper.getFirstHeader("Cache-Control").getValue()); } } ././@LongLink0100644 0000000 0000000 00000000174 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestResponseCachingPolicy.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestRes0100644 0000000 0000000 00000066240 12301751715 032316 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.Date; import java.util.Random; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.ProtocolVersion; import org.apache.http.client.methods.HttpOptions; import org.apache.http.client.utils.DateUtils; import org.apache.http.message.BasicHttpRequest; import org.apache.http.message.BasicHttpResponse; import org.apache.http.message.BasicStatusLine; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestResponseCachingPolicy { private static final ProtocolVersion HTTP_1_1 = new ProtocolVersion("HTTP", 1, 1); private ResponseCachingPolicy policy; private HttpResponse response; private HttpRequest request; private final int[] acceptableCodes = new int[] { HttpStatus.SC_OK, HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION, HttpStatus.SC_MULTIPLE_CHOICES, HttpStatus.SC_MOVED_PERMANENTLY, HttpStatus.SC_GONE }; private Date now; private Date tenSecondsFromNow; private Date sixSecondsAgo; @Before public void setUp() throws Exception { now = new Date(); sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L); policy = new ResponseCachingPolicy(0, true, false, false); request = new BasicHttpRequest("GET","/",HTTP_1_1); response = new BasicHttpResponse( new BasicStatusLine(HTTP_1_1, HttpStatus.SC_OK, "")); response.setHeader("Date", DateUtils.formatDate(new Date())); response.setHeader("Content-Length", "0"); } @Test public void testIsGetCacheable() { Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void testResponsesToRequestsWithAuthorizationHeadersAreNotCacheableBySharedCache() { request = new BasicHttpRequest("GET","/",HTTP_1_1); request.setHeader("Authorization","Basic dXNlcjpwYXNzd2Q="); Assert.assertFalse(policy.isResponseCacheable(request,response)); } @Test public void testResponsesToRequestsWithAuthorizationHeadersAreCacheableByNonSharedCache() { policy = new ResponseCachingPolicy(0, false, false, false); request = new BasicHttpRequest("GET","/",HTTP_1_1); request.setHeader("Authorization","Basic dXNlcjpwYXNzd2Q="); Assert.assertTrue(policy.isResponseCacheable(request,response)); } @Test public void testAuthorizedResponsesWithSMaxAgeAreCacheable() { request = new BasicHttpRequest("GET","/",HTTP_1_1); request.setHeader("Authorization","Basic dXNlcjpwYXNzd2Q="); response.setHeader("Cache-Control","s-maxage=3600"); Assert.assertTrue(policy.isResponseCacheable(request,response)); } @Test public void testAuthorizedResponsesWithMustRevalidateAreCacheable() { request = new BasicHttpRequest("GET","/",HTTP_1_1); request.setHeader("Authorization","Basic dXNlcjpwYXNzd2Q="); response.setHeader("Cache-Control","must-revalidate"); Assert.assertTrue(policy.isResponseCacheable(request,response)); } @Test public void testAuthorizedResponsesWithCacheControlPublicAreCacheable() { request = new BasicHttpRequest("GET","/",HTTP_1_1); request.setHeader("Authorization","Basic dXNlcjpwYXNzd2Q="); response.setHeader("Cache-Control","public"); Assert.assertTrue(policy.isResponseCacheable(request,response)); } @Test public void testAuthorizedResponsesWithCacheControlMaxAgeAreNotCacheable() { request = new BasicHttpRequest("GET","/",HTTP_1_1); request.setHeader("Authorization","Basic dXNlcjpwYXNzd2Q="); response.setHeader("Cache-Control","max-age=3600"); Assert.assertFalse(policy.isResponseCacheable(request,response)); } @Test public void test203ResponseCodeIsCacheable() { response.setStatusCode(HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION); Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void test206ResponseCodeIsNotCacheable() { response.setStatusCode(HttpStatus.SC_PARTIAL_CONTENT); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void test206ResponseCodeIsNotCacheableUsingSharedPublicCache() { policy = new ResponseCachingPolicy(0, true, false, false); request.setHeader("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); response.setStatusCode(HttpStatus.SC_PARTIAL_CONTENT); response.setHeader("Cache-Control", "public"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void test300ResponseCodeIsCacheable() { response.setStatusCode(HttpStatus.SC_MULTIPLE_CHOICES); Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void test301ResponseCodeIsCacheable() { response.setStatusCode(HttpStatus.SC_MOVED_PERMANENTLY); Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void test410ResponseCodeIsCacheable() { response.setStatusCode(HttpStatus.SC_GONE); Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void testPlain302ResponseCodeIsNotCacheable() { response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY); response.removeHeaders("Expires"); response.removeHeaders("Cache-Control"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testPlain303ResponseCodeIsNotCacheableUnderDefaultBehavior() { response.setStatusCode(HttpStatus.SC_SEE_OTHER); response.removeHeaders("Expires"); response.removeHeaders("Cache-Control"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testPlain303ResponseCodeIsNotCacheableEvenIf303CachingEnabled() { policy = new ResponseCachingPolicy(0, true, false, true); response.setStatusCode(HttpStatus.SC_SEE_OTHER); response.removeHeaders("Expires"); response.removeHeaders("Cache-Control"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testPlain307ResponseCodeIsNotCacheable() { response.setStatusCode(HttpStatus.SC_TEMPORARY_REDIRECT); response.removeHeaders("Expires"); response.removeHeaders("Cache-Control"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testNon206WithExplicitExpiresIsCacheable() { final int status = getRandomStatus(); response.setStatusCode(status); response.setHeader("Expires", DateUtils.formatDate(new Date())); Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void testNon206WithMaxAgeIsCacheable() { final int status = getRandomStatus(); response.setStatusCode(status); response.setHeader("Cache-Control", "max-age=0"); Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void testNon206WithSMaxAgeIsCacheable() { final int status = getRandomStatus(); response.setStatusCode(status); response.setHeader("Cache-Control", "s-maxage=0"); Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void testNon206WithMustRevalidateIsCacheable() { final int status = getRandomStatus(); response.setStatusCode(status); response.setHeader("Cache-Control", "must-revalidate"); Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void testNon206WithProxyRevalidateIsCacheable() { final int status = getRandomStatus(); response.setStatusCode(status); response.setHeader("Cache-Control", "proxy-revalidate"); Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void testNon206WithPublicCacheControlIsCacheable() { final int status = getRandomStatus(); response.setStatusCode(status); response.setHeader("Cache-Control", "public"); Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void testNon206WithPrivateCacheControlIsNotCacheableBySharedCache() { final int status = getRandomStatus(); response.setStatusCode(status); response.setHeader("Cache-Control", "private"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void test200ResponseWithPrivateCacheControlIsCacheableByNonSharedCache() { policy = new ResponseCachingPolicy(0, false, false, false); response.setStatusCode(HttpStatus.SC_OK); response.setHeader("Cache-Control", "private"); Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void testIsGetWithNoCacheCacheable() { response.addHeader("Cache-Control", "no-cache"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testIsGetWithNoStoreCacheable() { response.addHeader("Cache-Control", "no-store"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testIsGetWithNoStoreEmbeddedInListCacheable() { response.addHeader("Cache-Control", "public, no-store"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testIsGetWithNoCacheEmbeddedInListCacheable() { response.addHeader("Cache-Control", "public, no-cache"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testIsGetWithNoCacheEmbeddedInListAfterFirstHeaderCacheable() { response.addHeader("Cache-Control", "max-age=20"); response.addHeader("Cache-Control", "public, no-cache"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testIsGetWithNoStoreEmbeddedInListAfterFirstHeaderCacheable() { response.addHeader("Cache-Control", "max-age=20"); response.addHeader("Cache-Control", "public, no-store"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testIsGetWithAnyCacheControlCacheable() { response.addHeader("Cache-Control", "max=10"); Assert.assertTrue(policy.isResponseCacheable("GET", response)); response = new BasicHttpResponse( new BasicStatusLine(HTTP_1_1, HttpStatus.SC_OK, "")); response.setHeader("Date", DateUtils.formatDate(new Date())); response.addHeader("Cache-Control", "no-transform"); response.setHeader("Content-Length", "0"); Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void testIsGetWithout200Cacheable() { HttpResponse response = new BasicHttpResponse(new BasicStatusLine(HTTP_1_1, HttpStatus.SC_NOT_FOUND, "")); Assert.assertFalse(policy.isResponseCacheable("GET", response)); response = new BasicHttpResponse(new BasicStatusLine(HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "")); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testVaryStarIsNotCacheable() { response.setHeader("Vary", "*"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testVaryStarIsNotCacheableUsingSharedPublicCache() { policy = new ResponseCachingPolicy(0, true, false, false); request.setHeader("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); response.setHeader("Cache-Control", "public"); response.setHeader("Vary", "*"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void testIsGetWithVaryHeaderCacheable() { response.addHeader("Vary", "Accept-Encoding"); Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void testIsArbitraryMethodCacheable() { Assert.assertFalse(policy.isResponseCacheable("PUT", response)); Assert.assertFalse(policy.isResponseCacheable("get", response)); } @Test public void testIsArbitraryMethodCacheableUsingSharedPublicCache() { policy = new ResponseCachingPolicy(0, true, false, false); request = new HttpOptions("http://foo.example.com/"); request.setHeader("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); response.setStatusCode(HttpStatus.SC_NO_CONTENT); response.setHeader("Cache-Control", "public"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void testResponsesToRequestsWithNoStoreAreNotCacheable() { request.setHeader("Cache-Control","no-store"); response.setHeader("Cache-Control","public"); Assert.assertFalse(policy.isResponseCacheable(request,response)); } @Test public void testResponsesWithMultipleAgeHeadersAreNotCacheable() { response.addHeader("Age", "3"); response.addHeader("Age", "5"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testResponsesWithMultipleAgeHeadersAreNotCacheableUsingSharedPublicCache() { policy = new ResponseCachingPolicy(0, true, false, false); request.setHeader("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); response.setHeader("Cache-Control", "public"); response.addHeader("Age", "3"); response.addHeader("Age", "5"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void testResponsesWithMultipleDateHeadersAreNotCacheable() { response.addHeader("Date", DateUtils.formatDate(now)); response.addHeader("Date", DateUtils.formatDate(sixSecondsAgo)); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testResponsesWithMultipleDateHeadersAreNotCacheableUsingSharedPublicCache() { policy = new ResponseCachingPolicy(0, true, false, false); request.setHeader("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); response.setHeader("Cache-Control", "public"); response.addHeader("Date", DateUtils.formatDate(now)); response.addHeader("Date", DateUtils.formatDate(sixSecondsAgo)); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void testResponsesWithMalformedDateHeadersAreNotCacheable() { response.addHeader("Date", "garbage"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testResponsesWithMalformedDateHeadersAreNotCacheableUsingSharedPublicCache() { policy = new ResponseCachingPolicy(0, true, false, false); request.setHeader("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); response.setHeader("Cache-Control", "public"); response.addHeader("Date", "garbage"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void testResponsesWithMultipleExpiresHeadersAreNotCacheable() { final Date now = new Date(); final Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); response.addHeader("Expires", DateUtils.formatDate(now)); response.addHeader("Expires", DateUtils.formatDate(sixSecondsAgo)); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testResponsesWithMultipleExpiresHeadersAreNotCacheableUsingSharedPublicCache() { policy = new ResponseCachingPolicy(0, true, false, false); request.setHeader("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); response.setHeader("Cache-Control", "public"); final Date now = new Date(); final Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L); response.addHeader("Expires", DateUtils.formatDate(now)); response.addHeader("Expires", DateUtils.formatDate(sixSecondsAgo)); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void testResponsesWithoutDateHeadersAreNotCacheable() { response.removeHeaders("Date"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testResponseThatHasTooMuchContentIsNotCacheable() { response.setHeader("Content-Length", "9000"); Assert.assertFalse(policy.isResponseCacheable("GET", response)); } @Test public void testResponseThatHasTooMuchContentIsNotCacheableUsingSharedPublicCache() { policy = new ResponseCachingPolicy(0, true, false, false); request.setHeader("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); response.setHeader("Cache-Control", "public"); response.setHeader("Content-Length", "9000"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void testResponsesThatAreSmallEnoughAreCacheable() { response.setHeader("Content-Length", "0"); Assert.assertTrue(policy.isResponseCacheable("GET", response)); } @Test public void testResponsesToGETWithQueryParamsButNoExplicitCachingAreNotCacheable() { request = new BasicHttpRequest("GET", "/foo?s=bar"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void testResponsesToGETWithQueryParamsButNoExplicitCachingAreNotCacheableEvenWhen1_0QueryCachingDisabled() { policy = new ResponseCachingPolicy(0, true, true, false); request = new BasicHttpRequest("GET", "/foo?s=bar"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void testResponsesToGETWithQueryParamsAndExplicitCachingAreCacheable() { request = new BasicHttpRequest("GET", "/foo?s=bar"); response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)); Assert.assertTrue(policy.isResponseCacheable(request, response)); } @Test public void testResponsesToGETWithQueryParamsAndExplicitCachingAreCacheableEvenWhen1_0QueryCachingDisabled() { policy = new ResponseCachingPolicy(0, true, true, false); request = new BasicHttpRequest("GET", "/foo?s=bar"); response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)); Assert.assertTrue(policy.isResponseCacheable(request, response)); } @Test public void getsWithQueryParametersDirectlyFrom1_0OriginsAreNotCacheable() { request = new BasicHttpRequest("GET", "/foo?s=bar"); response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void getsWithQueryParametersDirectlyFrom1_0OriginsAreNotCacheableEvenWithSetting() { policy = new ResponseCachingPolicy(0, true, true, false); request = new BasicHttpRequest("GET", "/foo?s=bar"); response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void getsWithQueryParametersDirectlyFrom1_0OriginsAreCacheableWithExpires() { request = new BasicHttpRequest("GET", "/foo?s=bar"); response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK"); response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)); Assert.assertTrue(policy.isResponseCacheable(request, response)); } @Test public void getsWithQueryParametersDirectlyFrom1_0OriginsCanBeNotCacheableEvenWithExpires() { policy = new ResponseCachingPolicy(0, true, true, false); request = new BasicHttpRequest("GET", "/foo?s=bar"); response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK"); response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void getsWithQueryParametersFrom1_0OriginsViaProxiesAreNotCacheable() { request = new BasicHttpRequest("GET", "/foo?s=bar"); response.setHeader("Via", "1.0 someproxy"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void getsWithQueryParametersFrom1_0OriginsViaProxiesAreCacheableWithExpires() { request = new BasicHttpRequest("GET", "/foo?s=bar"); final Date now = new Date(); final Date tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L); response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)); response.setHeader("Via", "1.0 someproxy"); Assert.assertTrue(policy.isResponseCacheable(request, response)); } @Test public void getsWithQueryParametersFrom1_0OriginsViaProxiesCanNotBeCacheableEvenWithExpires() { policy = new ResponseCachingPolicy(0, true, true, true); request = new BasicHttpRequest("GET", "/foo?s=bar"); final Date now = new Date(); final Date tenSecondsFromNow = new Date(now.getTime() + 10 * 1000L); response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)); response.setHeader("Via", "1.0 someproxy"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void getsWithQueryParametersFrom1_0OriginsViaExplicitProxiesAreCacheableWithExpires() { request = new BasicHttpRequest("GET", "/foo?s=bar"); response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)); response.setHeader("Via", "HTTP/1.0 someproxy"); Assert.assertTrue(policy.isResponseCacheable(request, response)); } @Test public void getsWithQueryParametersFrom1_0OriginsViaExplicitProxiesCanNotBeCacheableEvenWithExpires() { policy = new ResponseCachingPolicy(0, true, true, true); request = new BasicHttpRequest("GET", "/foo?s=bar"); response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)); response.setHeader("Via", "HTTP/1.0 someproxy"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void getsWithQueryParametersFrom1_1OriginsVia1_0ProxiesAreCacheableWithExpires() { request = new BasicHttpRequest("GET", "/foo?s=bar"); response = new BasicHttpResponse(HttpVersion.HTTP_1_0, HttpStatus.SC_OK, "OK"); response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)); response.setHeader("Via", "1.1 someproxy"); Assert.assertTrue(policy.isResponseCacheable(request, response)); } @Test public void notCacheableIfExpiresEqualsDateAndNoCacheControl() { response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Expires", DateUtils.formatDate(now)); response.removeHeaders("Cache-Control"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void notCacheableIfExpiresPrecedesDateAndNoCacheControl() { response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Expires", DateUtils.formatDate(sixSecondsAgo)); response.removeHeaders("Cache-Control"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void test302WithExplicitCachingHeaders() { response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY); response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Cache-Control","max-age=300"); Assert.assertTrue(policy.isResponseCacheable(request, response)); } @Test public void test303WithExplicitCachingHeadersUnderDefaultBehavior() { // RFC 2616 says: 303 should not be cached response.setStatusCode(HttpStatus.SC_SEE_OTHER); response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Cache-Control","max-age=300"); Assert.assertFalse(policy.isResponseCacheable(request, response)); } @Test public void test303WithExplicitCachingHeadersWhenPermittedByConfig() { // HTTPbis working group says ok if explicitly indicated by // response headers policy = new ResponseCachingPolicy(0, true, false, true); response.setStatusCode(HttpStatus.SC_SEE_OTHER); response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Cache-Control","max-age=300"); Assert.assertTrue(policy.isResponseCacheable(request, response)); } @Test public void test307WithExplicitCachingHeaders() { response.setStatusCode(HttpStatus.SC_TEMPORARY_REDIRECT); response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Cache-Control","max-age=300"); Assert.assertTrue(policy.isResponseCacheable(request, response)); } @Test public void otherStatusCodesAreCacheableWithExplicitCachingHeaders() { response.setStatusCode(HttpStatus.SC_NOT_FOUND); response.setHeader("Date", DateUtils.formatDate(now)); response.setHeader("Cache-Control","max-age=300"); Assert.assertTrue(policy.isResponseCacheable(request, response)); } private int getRandomStatus() { final int rnd = new Random().nextInt(acceptableCodes.length); return acceptableCodes[rnd]; } } ././@LongLink0100644 0000000 0000000 00000000201 12302131606 011616 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestResponseProtocolCompliance.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestRes0100644 0000000 0000000 00000014136 12301751715 032313 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.util.Date; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.utils.DateUtils; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.InputStreamEntity; import org.apache.http.message.BasicHttpEntityEnclosingRequest; import org.apache.http.message.BasicHttpResponse; import org.junit.Before; import org.junit.Test; public class TestResponseProtocolCompliance { private ResponseProtocolCompliance impl; @Before public void setUp() { impl = new ResponseProtocolCompliance(); } private static class Flag { public boolean set; } private void setMinimalResponseHeaders(final HttpResponse resp) { resp.setHeader("Date", DateUtils.formatDate(new Date())); resp.setHeader("Server", "MyServer/1.0"); } private ByteArrayInputStream makeTrackableBody(final int nbytes, final Flag closed) { final byte[] buf = HttpTestUtils.getRandomBytes(nbytes); final ByteArrayInputStream bais = new ByteArrayInputStream(buf) { @Override public void close() { closed.set = true; } }; return bais; } private HttpResponse makePartialResponse(final int nbytes) { final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PARTIAL_CONTENT, "Partial Content"); setMinimalResponseHeaders(resp); resp.setHeader("Content-Length","" + nbytes); resp.setHeader("Content-Range","0-127/256"); return resp; } @Test public void consumesBodyIfOriginSendsOneInResponseToHEAD() throws Exception { final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(new HttpHead("http://foo.example.com/")); final int nbytes = 128; final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); setMinimalResponseHeaders(resp); resp.setHeader("Content-Length","" + nbytes); final Flag closed = new Flag(); final ByteArrayInputStream bais = makeTrackableBody(nbytes, closed); resp.setEntity(new InputStreamEntity(bais, -1)); impl.ensureProtocolCompliance(wrapper, resp); assertNull(resp.getEntity()); assertTrue(closed.set || bais.read() == -1); } @Test(expected=ClientProtocolException.class) public void throwsExceptionIfOriginReturnsPartialResponseWhenNotRequested() throws Exception { final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/")); final int nbytes = 128; final HttpResponse resp = makePartialResponse(nbytes); resp.setEntity(HttpTestUtils.makeBody(nbytes)); impl.ensureProtocolCompliance(wrapper, resp); } @Test public void consumesPartialContentFromOriginEvenIfNotRequested() throws Exception { final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/")); final int nbytes = 128; final HttpResponse resp = makePartialResponse(nbytes); final Flag closed = new Flag(); final ByteArrayInputStream bais = makeTrackableBody(nbytes, closed); resp.setEntity(new InputStreamEntity(bais, -1)); try { impl.ensureProtocolCompliance(wrapper, resp); } catch (final ClientProtocolException expected) { } assertTrue(closed.set || bais.read() == -1); } @Test public void consumesBodyOf100ContinueResponseIfItArrives() throws Exception { final HttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest("POST", "/", HttpVersion.HTTP_1_1); final int nbytes = 128; req.setHeader("Content-Length","" + nbytes); req.setHeader("Content-Type", "application/octet-stream"); final HttpEntity postBody = new ByteArrayEntity(HttpTestUtils.getRandomBytes(nbytes)); req.setEntity(postBody); final HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(req); final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_CONTINUE, "Continue"); final Flag closed = new Flag(); final ByteArrayInputStream bais = makeTrackableBody(nbytes, closed); resp.setEntity(new InputStreamEntity(bais, -1)); try { impl.ensureProtocolCompliance(wrapper, resp); } catch (final ClientProtocolException expected) { } assertTrue(closed.set || bais.read() == -1); } } ././@LongLink0100644 0000000 0000000 00000000170 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestRFC5861Compliance.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestRFC0100644 0000000 0000000 00000061440 12301751713 032172 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.util.Date; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.client.methods.HttpRequestWrapper; import org.apache.http.client.utils.DateUtils; import org.apache.http.entity.InputStreamEntity; import org.apache.http.message.BasicHttpRequest; import org.junit.Test; /** * A suite of acceptance tests for compliance with RFC5861, which * describes the stale-if-error and stale-while-revalidate * Cache-Control extensions. */ public class TestRFC5861Compliance extends AbstractProtocolTest { /* * "The stale-if-error Cache-Control extension indicates that when an * error is encountered, a cached stale response MAY be used to satisfy * the request, regardless of other freshness information.When used as a * request Cache-Control extension, its scope of application is the request * it appears in; when used as a response Cache-Control extension, its * scope is any request applicable to the cached response in which it * occurs.Its value indicates the upper limit to staleness; when the cached * response is more stale than the indicated amount, the cached response * SHOULD NOT be used to satisfy the request, absent other information. * In this context, an error is any situation that would result in a * 500, 502, 503, or 504 HTTP response status code being returned." * * http://tools.ietf.org/html/rfc5861 */ @Test public void testStaleIfErrorInResponseIsTrueReturnsStaleEntryWithWarning() throws Exception{ final Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo, "public, max-age=5, stale-if-error=60"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp2 = HttpTestUtils.make500Response(); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); HttpTestUtils.assert110WarningFound(result); } @Test public void testConsumesErrorResponseWhenServingStale() throws Exception{ final Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo, "public, max-age=5, stale-if-error=60"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp2 = HttpTestUtils.make500Response(); final byte[] body = HttpTestUtils.getRandomBytes(101); final ByteArrayInputStream buf = new ByteArrayInputStream(body); final ConsumableInputStream cis = new ConsumableInputStream(buf); final HttpEntity entity = new InputStreamEntity(cis, 101); resp2.setEntity(entity); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); impl.execute(route, req2, context, null); verifyMocks(); assertTrue(cis.wasClosed()); } @Test public void testStaleIfErrorInResponseYieldsToMustRevalidate() throws Exception{ final Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo, "public, max-age=5, stale-if-error=60, must-revalidate"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp2 = HttpTestUtils.make500Response(); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertTrue(HttpStatus.SC_OK != result.getStatusLine().getStatusCode()); } @Test public void testStaleIfErrorInResponseYieldsToProxyRevalidateForSharedCache() throws Exception{ assertTrue(config.isSharedCache()); final Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo, "public, max-age=5, stale-if-error=60, proxy-revalidate"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp2 = HttpTestUtils.make500Response(); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertTrue(HttpStatus.SC_OK != result.getStatusLine().getStatusCode()); } @Test public void testStaleIfErrorInResponseNeedNotYieldToProxyRevalidateForPrivateCache() throws Exception{ final CacheConfig config = CacheConfig.custom() .setSharedCache(false).build(); impl = new CachingExec(mockBackend, new BasicHttpCache(config), config); final Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo, "public, max-age=5, stale-if-error=60, proxy-revalidate"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp2 = HttpTestUtils.make500Response(); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); HttpTestUtils.assert110WarningFound(result); } @Test public void testStaleIfErrorInResponseYieldsToExplicitFreshnessRequest() throws Exception{ final Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo, "public, max-age=5, stale-if-error=60"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("Cache-Control","min-fresh=2"); final HttpResponse resp2 = HttpTestUtils.make500Response(); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertTrue(HttpStatus.SC_OK != result.getStatusLine().getStatusCode()); } @Test public void testStaleIfErrorInRequestIsTrueReturnsStaleEntryWithWarning() throws Exception{ final Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo, "public, max-age=5"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("Cache-Control","public, stale-if-error=60"); final HttpResponse resp2 = HttpTestUtils.make500Response(); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); HttpTestUtils.assert110WarningFound(result); } @Test public void testStaleIfErrorInRequestIsTrueReturnsStaleNonRevalidatableEntryWithWarning() throws Exception { final Date tenSecondsAgo = new Date(new Date().getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); resp1.setHeader("Cache-Control", "public, max-age=5"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("Cache-Control", "public, stale-if-error=60"); final HttpResponse resp2 = HttpTestUtils.make500Response(); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); HttpTestUtils.assert110WarningFound(result); } @Test public void testStaleIfErrorInResponseIsFalseReturnsError() throws Exception{ final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo, "public, max-age=5, stale-if-error=2"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp2 = HttpTestUtils.make500Response(); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, result.getStatusLine().getStatusCode()); } @Test public void testStaleIfErrorInRequestIsFalseReturnsError() throws Exception{ final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); final HttpResponse resp1 = HttpTestUtils.make200Response(tenSecondsAgo, "public, max-age=5"); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest()); req2.setHeader("Cache-Control","stale-if-error=2"); final HttpResponse resp2 = HttpTestUtils.make500Response(); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, result.getStatusLine().getStatusCode()); } /* * When present in an HTTP response, the stale-while-revalidate Cache- * Control extension indicates that caches MAY serve the response in * which it appears after it becomes stale, up to the indicated number * of seconds. * * http://tools.ietf.org/html/rfc5861 */ @Test public void testStaleWhileRevalidateReturnsStaleEntryWithWarning() throws Exception { config = CacheConfig.custom() .setMaxCacheEntries(MAX_ENTRIES) .setMaxObjectSize(MAX_BYTES) .setAsynchronousWorkersMax(1) .build(); impl = new CachingExec(mockBackend, cache, config, new AsynchronousValidator(config)); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); resp1.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15"); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1).times(1,2); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode()); boolean warning110Found = false; for(final Header h : result.getHeaders("Warning")) { for(final WarningValue wv : WarningValue.getWarningValues(h)) { if (wv.getWarnCode() == 110) { warning110Found = true; break; } } } assertTrue(warning110Found); } @Test public void testStaleWhileRevalidateReturnsStaleNonRevalidatableEntryWithWarning() throws Exception { config = CacheConfig.custom().setMaxCacheEntries(MAX_ENTRIES).setMaxObjectSize(MAX_BYTES) .setAsynchronousWorkersMax(1).build(); impl = new CachingExec(mockBackend, cache, config, new AsynchronousValidator(config)); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); resp1.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15"); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1).times(1, 2); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode()); boolean warning110Found = false; for (final Header h : result.getHeaders("Warning")) { for (final WarningValue wv : WarningValue.getWarningValues(h)) { if (wv.getWarnCode() == 110) { warning110Found = true; break; } } } assertTrue(warning110Found); } @Test public void testCanAlsoServeStale304sWhileRevalidating() throws Exception { config = CacheConfig.custom() .setMaxCacheEntries(MAX_ENTRIES) .setMaxObjectSize(MAX_BYTES) .setAsynchronousWorkersMax(1) .setSharedCache(false) .build(); impl = new CachingExec(mockBackend, cache, config, new AsynchronousValidator(config)); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); resp1.setHeader("Cache-Control", "private, stale-while-revalidate=15"); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1).times(1,2); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("If-None-Match","\"etag\""); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode()); boolean warning110Found = false; for(final Header h : result.getHeaders("Warning")) { for(final WarningValue wv : WarningValue.getWarningValues(h)) { if (wv.getWarnCode() == 110) { warning110Found = true; break; } } } assertTrue(warning110Found); } @Test public void testStaleWhileRevalidateYieldsToMustRevalidate() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); config = CacheConfig.custom() .setMaxCacheEntries(MAX_ENTRIES) .setMaxObjectSize(MAX_BYTES) .setAsynchronousWorkersMax(1) .build(); impl = new CachingExec(mockBackend, cache, config); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15, must-revalidate"); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15, must-revalidate"); resp2.setHeader("ETag","\"etag\""); resp2.setHeader("Date", DateUtils.formatDate(now)); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode()); boolean warning110Found = false; for(final Header h : result.getHeaders("Warning")) { for(final WarningValue wv : WarningValue.getWarningValues(h)) { if (wv.getWarnCode() == 110) { warning110Found = true; break; } } } assertFalse(warning110Found); } @Test public void testStaleWhileRevalidateYieldsToProxyRevalidateForSharedCache() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); config = CacheConfig.custom() .setMaxCacheEntries(MAX_ENTRIES) .setMaxObjectSize(MAX_BYTES) .setAsynchronousWorkersMax(1) .setSharedCache(true) .build(); impl = new CachingExec(mockBackend, cache, config); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15, proxy-revalidate"); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15, proxy-revalidate"); resp2.setHeader("ETag","\"etag\""); resp2.setHeader("Date", DateUtils.formatDate(now)); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode()); boolean warning110Found = false; for(final Header h : result.getHeaders("Warning")) { for(final WarningValue wv : WarningValue.getWarningValues(h)) { if (wv.getWarnCode() == 110) { warning110Found = true; break; } } } assertFalse(warning110Found); } @Test public void testStaleWhileRevalidateYieldsToExplicitFreshnessRequest() throws Exception { final Date now = new Date(); final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L); config = CacheConfig.custom() .setMaxCacheEntries(MAX_ENTRIES) .setMaxObjectSize(MAX_BYTES) .setAsynchronousWorkersMax(1) .setSharedCache(true) .build(); impl = new CachingExec(mockBackend, cache, config); final HttpRequestWrapper req1 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); final HttpResponse resp1 = HttpTestUtils.make200Response(); resp1.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15"); resp1.setHeader("ETag","\"etag\""); resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo)); backendExpectsAnyRequestAndReturn(resp1); final HttpRequestWrapper req2 = HttpRequestWrapper.wrap( new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1)); req2.setHeader("Cache-Control","min-fresh=2"); final HttpResponse resp2 = HttpTestUtils.make200Response(); resp2.setHeader("Cache-Control", "public, max-age=5, stale-while-revalidate=15"); resp2.setHeader("ETag","\"etag\""); resp2.setHeader("Date", DateUtils.formatDate(now)); backendExpectsAnyRequestAndReturn(resp2); replayMocks(); impl.execute(route, req1, context, null); final HttpResponse result = impl.execute(route, req2, context, null); verifyMocks(); assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode()); boolean warning110Found = false; for(final Header h : result.getHeaders("Warning")) { for(final WarningValue wv : WarningValue.getWarningValues(h)) { if (wv.getWarnCode() == 110) { warning110Found = true; break; } } } assertFalse(warning110Found); } } ././@LongLink0100644 0000000 0000000 00000000200 12302131606 011615 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestSizeLimitedResponseReader.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestSiz0100644 0000000 0000000 00000020406 12301751715 032324 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.io.IOException; import java.lang.reflect.Proxy; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.http.HttpEntity; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicHttpResponse; import org.apache.http.util.EntityUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestSizeLimitedResponseReader { private static final long MAX_SIZE = 4; private HttpRequest request; private SizeLimitedResponseReader impl; @Before public void setUp() { request = new HttpGet("http://foo.example.com/bar"); } @Test public void testLargeResponseIsTooLarge() throws Exception { final byte[] buf = new byte[] { 1, 2, 3, 4, 5 }; final CloseableHttpResponse response = make200Response(buf); impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response); impl.readResponse(); final boolean tooLarge = impl.isLimitReached(); final HttpResponse result = impl.getReconstructedResponse(); final byte[] body = EntityUtils.toByteArray(result.getEntity()); Assert.assertTrue(tooLarge); Assert.assertArrayEquals(buf, body); } @Test public void testExactSizeResponseIsNotTooLarge() throws Exception { final byte[] buf = new byte[] { 1, 2, 3, 4 }; final CloseableHttpResponse response = make200Response(buf); impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response); impl.readResponse(); final boolean tooLarge = impl.isLimitReached(); final HttpResponse reconstructed = impl.getReconstructedResponse(); final byte[] result = EntityUtils.toByteArray(reconstructed.getEntity()); Assert.assertFalse(tooLarge); Assert.assertArrayEquals(buf, result); } @Test public void testSmallResponseIsNotTooLarge() throws Exception { final byte[] buf = new byte[] { 1, 2, 3 }; final CloseableHttpResponse response = make200Response(buf); impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response); impl.readResponse(); final boolean tooLarge = impl.isLimitReached(); final HttpResponse reconstructed = impl.getReconstructedResponse(); final byte[] result = EntityUtils.toByteArray(reconstructed.getEntity()); Assert.assertFalse(tooLarge); Assert.assertArrayEquals(buf, result); } @Test public void testResponseWithNoEntityIsNotTooLarge() throws Exception { final CloseableHttpResponse response = make200Response(); impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response); impl.readResponse(); final boolean tooLarge = impl.isLimitReached(); Assert.assertFalse(tooLarge); } @Test public void testTooLargeEntityHasOriginalContentTypes() throws Exception { final CloseableHttpResponse response = make200Response(); final StringEntity entity = new StringEntity("large entity content"); response.setEntity(entity); impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response); impl.readResponse(); final boolean tooLarge = impl.isLimitReached(); final HttpResponse result = impl.getReconstructedResponse(); final HttpEntity reconstructedEntity = result.getEntity(); Assert.assertEquals(entity.getContentEncoding(), reconstructedEntity.getContentEncoding()); Assert.assertEquals(entity.getContentType(), reconstructedEntity.getContentType()); final String content = EntityUtils.toString(reconstructedEntity); Assert.assertTrue(tooLarge); Assert.assertEquals("large entity content", content); } @Test public void testTooLargeResponseCombinedClosed() throws Exception { final AtomicBoolean closed = new AtomicBoolean(false); final CloseableHttpResponse response = (CloseableHttpResponse) Proxy .newProxyInstance(ResponseProxyHandler.class.getClassLoader(), new Class[] { CloseableHttpResponse.class }, new ResponseProxyHandler(new BasicHttpResponse( HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK")) { @Override public void close() throws IOException { closed.set(true); } }); final StringEntity entity = new StringEntity("large entity content"); response.setEntity(entity); impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response); impl.readResponse(); final boolean tooLarge = impl.isLimitReached(); final CloseableHttpResponse result = impl.getReconstructedResponse(); try { final HttpEntity reconstructedEntity = result.getEntity(); Assert.assertEquals(entity.getContentEncoding(), reconstructedEntity.getContentEncoding()); Assert.assertEquals(entity.getContentType(), reconstructedEntity.getContentType()); Assert.assertFalse(closed.get()); final String content = EntityUtils.toString(reconstructedEntity); Assert.assertTrue(tooLarge); Assert.assertEquals("large entity content", content); } finally { result.close(); } Assert.assertTrue(closed.get()); } @Test public void testResponseCopiesAllOriginalHeaders() throws Exception { final byte[] buf = new byte[] { 1, 2, 3 }; final CloseableHttpResponse response = make200Response(buf); response.setHeader("Content-Encoding", "gzip"); impl = new SizeLimitedResponseReader(new HeapResourceFactory(), MAX_SIZE, request, response); impl.readResponse(); final boolean tooLarge = impl.isLimitReached(); final HttpResponse reconstructed = impl.getReconstructedResponse(); final byte[] result = EntityUtils.toByteArray(reconstructed.getEntity()); Assert.assertFalse(tooLarge); Assert.assertArrayEquals(buf, result); Assert.assertEquals("gzip", reconstructed.getFirstHeader("Content-Encoding").getValue()); } private CloseableHttpResponse make200Response() { return Proxies.enhanceResponse(new BasicHttpResponse( HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK")); } private CloseableHttpResponse make200Response(final byte[] buf) { final HttpResponse response = new BasicHttpResponse( HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); response.setEntity(new ByteArrayEntity(buf)); return Proxies.enhanceResponse(response); } } ././@LongLink0100644 0000000 0000000 00000000217 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestStaleWhileRevalidationReleasesConnection.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestSta0100644 0000000 0000000 00000026005 12301751715 032307 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.MethodNotSupportedException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.cache.CacheResponseStatus; import org.apache.http.client.cache.HttpCacheContext; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.localserver.LocalTestServer; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Locale; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; /** * Test that after background validation that a subsequent request for non cached * conent can be made. This verifies that the connection has been release back to * the pool by the AsynchronousValidationRequest. */ public class TestStaleWhileRevalidationReleasesConnection { private static final EchoViaHeaderHandler cacheHandler = new EchoViaHeaderHandler(); protected LocalTestServer localServer; private int port; private CloseableHttpClient client; private final String url = "/static/dom"; private final String url2 = "2"; @Before public void start() throws Exception { this.localServer = new LocalTestServer(null, null); this.localServer.register(url +"*", new EchoViaHeaderHandler()); localServer.setTimeout(5000); this.localServer.start(); port = this.localServer.getServiceAddress().getPort(); final CacheConfig cacheConfig = CacheConfig.custom() .setMaxCacheEntries(100) .setMaxObjectSize(15) //1574 .setAsynchronousWorkerIdleLifetimeSecs(60) .setAsynchronousWorkersMax(1) .setAsynchronousWorkersCore(1) .setRevalidationQueueSize(100) .setSharedCache(true) .build(); final HttpClientBuilder clientBuilder = CachingHttpClientBuilder.create().setCacheConfig(cacheConfig); clientBuilder.setMaxConnTotal(1); clientBuilder.setMaxConnPerRoute(1); final RequestConfig config = RequestConfig.custom() .setSocketTimeout(10000) .setConnectTimeout(10000) .setConnectionRequestTimeout(1000) .build(); clientBuilder.setDefaultRequestConfig(config); client = clientBuilder.build(); } @After public void stop() { if (this.localServer != null) { try { this.localServer.stop(); } catch(final Exception e) { e.printStackTrace(); } } try { client.close(); } catch(final IOException e) { e.printStackTrace(); } } @Test public void testStaleWhileRevalidate() { final String urlToCall = "http://localhost:"+port + url; final HttpContext localContext = new BasicHttpContext(); Exception requestException = null; // This will fetch from backend. requestException = sendRequest(client, localContext,urlToCall,null); assertNull(requestException); CacheResponseStatus responseStatus = (CacheResponseStatus) localContext.getAttribute(HttpCacheContext.CACHE_RESPONSE_STATUS); assertEquals(CacheResponseStatus.CACHE_MISS,responseStatus); try { Thread.sleep(1000); } catch (final Exception e) { } // These will be cached requestException = sendRequest(client, localContext,urlToCall,null); assertNull(requestException); responseStatus = (CacheResponseStatus) localContext.getAttribute(HttpCacheContext.CACHE_RESPONSE_STATUS); assertEquals(CacheResponseStatus.CACHE_HIT,responseStatus); requestException = sendRequest(client, localContext,urlToCall,null); assertNull(requestException); responseStatus = (CacheResponseStatus) localContext.getAttribute(HttpCacheContext.CACHE_RESPONSE_STATUS); assertEquals(CacheResponseStatus.CACHE_HIT,responseStatus); // wait, so that max-age is expired try { Thread.sleep(4000); } catch (final Exception e) { } // This will cause a revalidation to occur requestException = sendRequest(client, localContext,urlToCall,"This is new content that is bigger than cache limit"); assertNull(requestException); responseStatus = (CacheResponseStatus) localContext.getAttribute(HttpCacheContext.CACHE_RESPONSE_STATUS); assertEquals(CacheResponseStatus.CACHE_HIT,responseStatus); try { Thread.sleep(1000); } catch (final Exception e) { } // fetch a different content This will hang due to connection leak in revalidation requestException = sendRequest(client, localContext,urlToCall+url2,null); if(requestException!=null) { requestException.printStackTrace(); } assertNull(requestException); } static Exception sendRequest(final HttpClient cachingClient, final HttpContext localContext , final String url, final String content) { final HttpGet httpget = new HttpGet(url); if(content!=null) { httpget.setHeader(cacheHandler.getUserContentHeader(),content); } HttpResponse response = null; try { response = cachingClient.execute(httpget, localContext); return null; } catch (final ClientProtocolException e1) { return e1; } catch (final IOException e1) { return e1; } finally { if(response!=null) { final HttpEntity entity = response.getEntity(); try { IOUtils.consume(entity); } catch (final IOException e) { e.printStackTrace(); } } } } public static class EchoViaHeaderHandler implements HttpRequestHandler { private final String CACHE_CONTROL_HEADER = "Cache-Control"; private final byte[] DEFAULT_CONTENT; private final String DEFAULT_CLIENT_CONTROLLED_CONTENT_HEADER; private final String DEFAULT_RESPONSE_CACHE_HEADER; // public default constructor public EchoViaHeaderHandler() { this("ECHO-CONTENT","abc".getBytes(), "public, max-age=3, stale-while-revalidate=5"); } public EchoViaHeaderHandler(final String contentHeader,final byte[] content, final String defaultResponseCacheHeader) { DEFAULT_CLIENT_CONTROLLED_CONTENT_HEADER = contentHeader; DEFAULT_CONTENT = content; DEFAULT_RESPONSE_CACHE_HEADER = defaultResponseCacheHeader; } /** * Return the header the user can set the content that will be returned by the server * @return */ public String getUserContentHeader() { return DEFAULT_CLIENT_CONTROLLED_CONTENT_HEADER; } /** * Handles a request by echoing the incoming request entity. * If there is no request entity, an empty document is returned. * * @param request the request * @param response the response * @param context the context * * @throws org.apache.http.HttpException in case of a problem * @throws java.io.IOException in case of an IO problem */ public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { final String method = request.getRequestLine().getMethod().toUpperCase(Locale.ENGLISH); if (!"GET".equals(method) && !"POST".equals(method) && !"PUT".equals(method) ) { throw new MethodNotSupportedException (method + " not supported by " + getClass().getName()); } response.setStatusCode(org.apache.http.HttpStatus.SC_OK); response.addHeader("Cache-Control",getCacheContent(request)); final byte[] content = getHeaderContent(request); final ByteArrayEntity bae = new ByteArrayEntity(content); response.setHeader("Connection","keep-alive"); response.setEntity(bae); } // handle public byte[] getHeaderContent(final HttpRequest request) { final Header contentHeader = request.getFirstHeader(DEFAULT_CLIENT_CONTROLLED_CONTENT_HEADER); if(contentHeader!=null) { try { return contentHeader.getValue().getBytes("UTF-8"); } catch(final UnsupportedEncodingException e) { return contentHeader.getValue().getBytes(); } } else { return DEFAULT_CONTENT; } } public String getCacheContent(final HttpRequest request) { final Header contentHeader = request.getFirstHeader(CACHE_CONTROL_HEADER); if(contentHeader!=null) { return contentHeader.getValue(); } else { return DEFAULT_RESPONSE_CACHE_HEADER; } } } // class EchoHandler } ././@LongLink0100644 0000000 0000000 00000000163 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestWarningValue.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestWar0100644 0000000 0000000 00000023632 12301751715 032314 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache; import java.util.Date; import org.apache.http.Header; import org.apache.http.client.utils.DateUtils; import org.apache.http.message.BasicHeader; import org.junit.Assert; import org.junit.Test; public class TestWarningValue { @Test public void testParseSingleWarnValue() { final Header h = new BasicHeader("Warning","110 fred \"stale\""); final WarningValue[] result = WarningValue.getWarningValues(h); Assert.assertEquals(1, result.length); final WarningValue wv = result[0]; Assert.assertEquals(110, wv.getWarnCode()); Assert.assertEquals("fred", wv.getWarnAgent()); Assert.assertEquals("\"stale\"", wv.getWarnText()); Assert.assertNull(wv.getWarnDate()); } @Test public void testParseMultipleWarnValues() { final Header h = new BasicHeader("Warning","110 fred \"stale\", 111 wilma \"other\""); final WarningValue[] result = WarningValue.getWarningValues(h); Assert.assertEquals(2, result.length); WarningValue wv = result[0]; Assert.assertEquals(110, wv.getWarnCode()); Assert.assertEquals("fred", wv.getWarnAgent()); Assert.assertEquals("\"stale\"", wv.getWarnText()); Assert.assertNull(wv.getWarnDate()); wv = result[1]; Assert.assertEquals(111, wv.getWarnCode()); Assert.assertEquals("wilma", wv.getWarnAgent()); Assert.assertEquals("\"other\"", wv.getWarnText()); Assert.assertNull(wv.getWarnDate()); } @Test public void testMidHeaderParseErrorRecovery() { final Header h = new BasicHeader("Warning","110 fred \"stale\", bogus, 111 wilma \"other\""); final WarningValue[] result = WarningValue.getWarningValues(h); Assert.assertEquals(2, result.length); WarningValue wv = result[0]; Assert.assertEquals(110, wv.getWarnCode()); Assert.assertEquals("fred", wv.getWarnAgent()); Assert.assertEquals("\"stale\"", wv.getWarnText()); Assert.assertNull(wv.getWarnDate()); wv = result[1]; Assert.assertEquals(111, wv.getWarnCode()); Assert.assertEquals("wilma", wv.getWarnAgent()); Assert.assertEquals("\"other\"", wv.getWarnText()); Assert.assertNull(wv.getWarnDate()); } @Test public void testTrickyCommaMidHeaderParseErrorRecovery() { final Header h = new BasicHeader("Warning","110 fred \"stale\", \"bogus, dude\", 111 wilma \"other\""); final WarningValue[] result = WarningValue.getWarningValues(h); Assert.assertEquals(2, result.length); WarningValue wv = result[0]; Assert.assertEquals(110, wv.getWarnCode()); Assert.assertEquals("fred", wv.getWarnAgent()); Assert.assertEquals("\"stale\"", wv.getWarnText()); Assert.assertNull(wv.getWarnDate()); wv = result[1]; Assert.assertEquals(111, wv.getWarnCode()); Assert.assertEquals("wilma", wv.getWarnAgent()); Assert.assertEquals("\"other\"", wv.getWarnText()); Assert.assertNull(wv.getWarnDate()); } @Test public void testParseErrorRecoveryAtEndOfHeader() { final Header h = new BasicHeader("Warning","110 fred \"stale\", 111 wilma \"other\", \"bogus, dude\""); final WarningValue[] result = WarningValue.getWarningValues(h); Assert.assertEquals(2, result.length); WarningValue wv = result[0]; Assert.assertEquals(110, wv.getWarnCode()); Assert.assertEquals("fred", wv.getWarnAgent()); Assert.assertEquals("\"stale\"", wv.getWarnText()); Assert.assertNull(wv.getWarnDate()); wv = result[1]; Assert.assertEquals(111, wv.getWarnCode()); Assert.assertEquals("wilma", wv.getWarnAgent()); Assert.assertEquals("\"other\"", wv.getWarnText()); Assert.assertNull(wv.getWarnDate()); } @Test public void testConstructSingleWarnValue() { final WarningValue impl = new WarningValue("110 fred \"stale\""); Assert.assertEquals(110, impl.getWarnCode()); Assert.assertEquals("fred", impl.getWarnAgent()); Assert.assertEquals("\"stale\"", impl.getWarnText()); Assert.assertNull(impl.getWarnDate()); } @Test public void testConstructWarnValueWithIPv4Address() { final WarningValue impl = new WarningValue("110 192.168.1.1 \"stale\""); Assert.assertEquals(110, impl.getWarnCode()); Assert.assertEquals("192.168.1.1", impl.getWarnAgent()); Assert.assertEquals("\"stale\"", impl.getWarnText()); Assert.assertNull(impl.getWarnDate()); } @Test public void testConstructWarnValueWithHostname() { final WarningValue impl = new WarningValue("110 foo.example.com \"stale\""); Assert.assertEquals(110, impl.getWarnCode()); Assert.assertEquals("foo.example.com", impl.getWarnAgent()); Assert.assertEquals("\"stale\"", impl.getWarnText()); Assert.assertNull(impl.getWarnDate()); } @Test public void testConstructWarnValueWithHostnameAndPort() { final WarningValue impl = new WarningValue("110 foo.example.com:8080 \"stale\""); Assert.assertEquals(110, impl.getWarnCode()); Assert.assertEquals("foo.example.com:8080", impl.getWarnAgent()); Assert.assertEquals("\"stale\"", impl.getWarnText()); Assert.assertNull(impl.getWarnDate()); } @Test public void testConstructWarnValueWithIPv4AddressAndPort() { final WarningValue impl = new WarningValue("110 192.168.1.1:8080 \"stale\""); Assert.assertEquals(110, impl.getWarnCode()); Assert.assertEquals("192.168.1.1:8080", impl.getWarnAgent()); Assert.assertEquals("\"stale\"", impl.getWarnText()); Assert.assertNull(impl.getWarnDate()); } @Test public void testConstructWarnValueWithPseudonym() { final WarningValue impl = new WarningValue("110 ca$hm0ney \"stale\""); Assert.assertEquals(110, impl.getWarnCode()); Assert.assertEquals("ca$hm0ney", impl.getWarnAgent()); Assert.assertEquals("\"stale\"", impl.getWarnText()); Assert.assertNull(impl.getWarnDate()); } @Test public void testConstructWarnValueWithTextWithSpaces() { final WarningValue impl = new WarningValue("110 fred \"stale stuff\""); Assert.assertEquals(110, impl.getWarnCode()); Assert.assertEquals("fred", impl.getWarnAgent()); Assert.assertEquals("\"stale stuff\"", impl.getWarnText()); Assert.assertNull(impl.getWarnDate()); } @Test public void testConstructWarnValueWithTextWithCommas() { final WarningValue impl = new WarningValue("110 fred \"stale, stuff\""); Assert.assertEquals(110, impl.getWarnCode()); Assert.assertEquals("fred", impl.getWarnAgent()); Assert.assertEquals("\"stale, stuff\"", impl.getWarnText()); Assert.assertNull(impl.getWarnDate()); } @Test public void testConstructWarnValueWithTextWithEscapedQuotes() { final WarningValue impl = new WarningValue("110 fred \"stale\\\" stuff\""); Assert.assertEquals(110, impl.getWarnCode()); Assert.assertEquals("fred", impl.getWarnAgent()); Assert.assertEquals("\"stale\\\" stuff\"", impl.getWarnText()); Assert.assertNull(impl.getWarnDate()); } @Test public void testConstructWarnValueWithAscTimeWarnDate() throws Exception { final WarningValue impl = new WarningValue("110 fred \"stale\" \"Sun Nov 6 08:49:37 1994\""); Assert.assertEquals(110, impl.getWarnCode()); Assert.assertEquals("fred", impl.getWarnAgent()); Assert.assertEquals("\"stale\"", impl.getWarnText()); final Date target = DateUtils.parseDate("Sun Nov 6 08:49:37 1994"); Assert.assertEquals(target, impl.getWarnDate()); } @Test public void testConstructWarnValueWithRFC850WarnDate() throws Exception { final WarningValue impl = new WarningValue("110 fred \"stale\" \"Sunday, 06-Nov-94 08:49:37 GMT\""); Assert.assertEquals(110, impl.getWarnCode()); Assert.assertEquals("fred", impl.getWarnAgent()); Assert.assertEquals("\"stale\"", impl.getWarnText()); final Date target = DateUtils.parseDate("Sunday, 06-Nov-94 08:49:37 GMT"); Assert.assertEquals(target, impl.getWarnDate()); } @Test public void testConstructWarnValueWithRFC1123WarnDate() throws Exception { final WarningValue impl = new WarningValue("110 fred \"stale\" \"Sun, 06 Nov 1994 08:49:37 GMT\""); Assert.assertEquals(110, impl.getWarnCode()); Assert.assertEquals("fred", impl.getWarnAgent()); Assert.assertEquals("\"stale\"", impl.getWarnText()); final Date target = DateUtils.parseDate("Sun, 06 Nov 1994 08:49:37 GMT"); Assert.assertEquals(target, impl.getWarnDate()); } } ././@LongLink0100644 0000000 0000000 00000000146 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache0040755 0000000 0000000 00000000000 12301751713 032274 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000206 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheHttpCacheStorage.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache0100644 0000000 0000000 00000021406 12301751713 032276 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.ehcache; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import junit.framework.TestCase; import net.sf.ehcache.Ehcache; import net.sf.ehcache.Element; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheEntrySerializer; import org.apache.http.client.cache.HttpCacheUpdateCallback; import org.apache.http.client.cache.HttpCacheUpdateException; import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.HttpTestUtils; import org.easymock.EasyMock; import org.junit.Test; public class TestEhcacheHttpCacheStorage extends TestCase { private Ehcache mockCache; private EhcacheHttpCacheStorage impl; private HttpCacheEntrySerializer mockSerializer; @Override public void setUp() { mockCache = EasyMock.createNiceMock(Ehcache.class); final CacheConfig config = CacheConfig.custom().setMaxUpdateRetries(1).build(); mockSerializer = EasyMock.createNiceMock(HttpCacheEntrySerializer.class); impl = new EhcacheHttpCacheStorage(mockCache, config, mockSerializer); } private void replayMocks(){ EasyMock.replay(mockCache); EasyMock.replay(mockSerializer); } private void verifyMocks(){ EasyMock.verify(mockCache); EasyMock.verify(mockSerializer); } @Test public void testCachePut() throws IOException { final String key = "foo"; final HttpCacheEntry value = HttpTestUtils.makeCacheEntry(); final Element e = new Element(key, new byte[]{}); mockSerializer.writeTo(EasyMock.same(value), EasyMock.isA(OutputStream.class)); mockCache.put(e); replayMocks(); impl.putEntry(key, value); verifyMocks(); } @Test public void testCacheGetNullEntry() throws IOException { final String key = "foo"; EasyMock.expect(mockCache.get(key)).andReturn(null); replayMocks(); final HttpCacheEntry resultingEntry = impl.getEntry(key); verifyMocks(); assertNull(resultingEntry); } @Test public void testCacheGet() throws IOException { final String key = "foo"; final HttpCacheEntry cachedValue = HttpTestUtils.makeCacheEntry(); final Element element = new Element(key, new byte[]{}); EasyMock.expect(mockCache.get(key)) .andReturn(element); EasyMock.expect(mockSerializer.readFrom(EasyMock.isA(InputStream.class))) .andReturn(cachedValue); replayMocks(); final HttpCacheEntry resultingEntry = impl.getEntry(key); verifyMocks(); assertSame(cachedValue, resultingEntry); } @Test public void testCacheRemove() { final String key = "foo"; EasyMock.expect(mockCache.remove(key)).andReturn(true); replayMocks(); impl.removeEntry(key); verifyMocks(); } @Test public void testCacheUpdateNullEntry() throws IOException, HttpCacheUpdateException { final String key = "foo"; final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); final Element element = new Element(key, new byte[]{}); final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback(){ public HttpCacheEntry update(final HttpCacheEntry old){ assertNull(old); return updatedValue; } }; // get empty old entry EasyMock.expect(mockCache.get(key)).andReturn(null); // put new entry mockSerializer.writeTo(EasyMock.same(updatedValue), EasyMock.isA(OutputStream.class)); mockCache.put(element); replayMocks(); impl.updateEntry(key, callback); verifyMocks(); } @Test public void testCacheUpdate() throws IOException, HttpCacheUpdateException { final String key = "foo"; final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); final Element existingElement = new Element(key, new byte[]{}); final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback(){ public HttpCacheEntry update(final HttpCacheEntry old){ assertEquals(existingValue, old); return updatedValue; } }; // get existing old entry EasyMock.expect(mockCache.get(key)).andReturn(existingElement); EasyMock.expect(mockSerializer.readFrom(EasyMock.isA(InputStream.class))).andReturn(existingValue); // update mockSerializer.writeTo(EasyMock.same(updatedValue), EasyMock.isA(OutputStream.class)); EasyMock.expect(mockCache.replace(EasyMock.same(existingElement), EasyMock.isA(Element.class))).andReturn(true); replayMocks(); impl.updateEntry(key, callback); verifyMocks(); } @Test public void testSingleCacheUpdateRetry() throws IOException, HttpCacheUpdateException { final String key = "foo"; final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); final Element existingElement = new Element(key, new byte[]{}); final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback(){ public HttpCacheEntry update(final HttpCacheEntry old){ assertEquals(existingValue, old); return updatedValue; } }; // get existing old entry, will happen twice EasyMock.expect(mockCache.get(key)).andReturn(existingElement).times(2); EasyMock.expect(mockSerializer.readFrom(EasyMock.isA(InputStream.class))).andReturn(existingValue).times(2); // update but fail mockSerializer.writeTo(EasyMock.same(updatedValue), EasyMock.isA(OutputStream.class)); EasyMock.expectLastCall().times(2); EasyMock.expect(mockCache.replace(EasyMock.same(existingElement), EasyMock.isA(Element.class))).andReturn(false); // update again and succeed EasyMock.expect(mockCache.replace(EasyMock.same(existingElement), EasyMock.isA(Element.class))).andReturn(true); replayMocks(); impl.updateEntry(key, callback); verifyMocks(); } @Test public void testCacheUpdateFail() throws IOException { final String key = "foo"; final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); final Element existingElement = new Element(key, new byte[]{}); final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback(){ public HttpCacheEntry update(final HttpCacheEntry old){ assertEquals(existingValue, old); return updatedValue; } }; // get existing old entry EasyMock.expect(mockCache.get(key)).andReturn(existingElement).times(2); EasyMock.expect(mockSerializer.readFrom(EasyMock.isA(InputStream.class))).andReturn(existingValue).times(2); // update but fail mockSerializer.writeTo(EasyMock.same(updatedValue), EasyMock.isA(OutputStream.class)); EasyMock.expectLastCall().times(2); EasyMock.expect(mockCache.replace(EasyMock.same(existingElement), EasyMock.isA(Element.class))).andReturn(false).times(2); replayMocks(); try{ impl.updateEntry(key, callback); fail("Expected HttpCacheUpdateException"); } catch (final HttpCacheUpdateException e) { } verifyMocks(); } } ././@LongLink0100644 0000000 0000000 00000000212 12302131606 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheProtocolRequirements.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache0100644 0000000 0000000 00000006423 12301751713 032300 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.ehcache; import net.sf.ehcache.CacheManager; import net.sf.ehcache.config.CacheConfiguration; import net.sf.ehcache.config.Configuration; import net.sf.ehcache.store.MemoryStoreEvictionPolicy; import org.apache.http.client.cache.HttpCacheStorage; import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.CachingExec; import org.apache.http.impl.client.cache.HeapResourceFactory; import org.apache.http.impl.client.cache.TestProtocolRequirements; import org.apache.http.impl.execchain.ClientExecChain; import org.easymock.classextension.EasyMock; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; public class TestEhcacheProtocolRequirements extends TestProtocolRequirements{ protected final String TEST_EHCACHE_NAME = "TestEhcacheProtocolRequirements-cache"; protected static CacheManager CACHE_MANAGER; @BeforeClass public static void setUpGlobal() { final Configuration config = new Configuration(); config.addDefaultCache( new CacheConfiguration("default", Integer.MAX_VALUE) .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LFU) .overflowToDisk(false)); CACHE_MANAGER = CacheManager.create(config); } @Override @Before public void setUp() { super.setUp(); config = CacheConfig.custom().setMaxObjectSize(MAX_BYTES).build(); if (CACHE_MANAGER.cacheExists(TEST_EHCACHE_NAME)){ CACHE_MANAGER.removeCache(TEST_EHCACHE_NAME); } CACHE_MANAGER.addCache(TEST_EHCACHE_NAME); final HttpCacheStorage storage = new EhcacheHttpCacheStorage(CACHE_MANAGER.getCache(TEST_EHCACHE_NAME)); mockBackend = EasyMock.createNiceMock(ClientExecChain.class); impl = new CachingExec(mockBackend, new HeapResourceFactory(), storage, config); } @After public void tearDown(){ CACHE_MANAGER.removeCache(TEST_EHCACHE_NAME); } @AfterClass public static void tearDownGlobal(){ CACHE_MANAGER.shutdown(); } } ././@LongLink0100644 0000000 0000000 00000000150 12302131606 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcached/httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcach0040755 0000000 0000000 00000000000 12301751716 032314 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000217 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcached/TestMemcachedCacheEntryFactoryImpl.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000003712 12301751716 032316 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.impl.client.cache.HttpTestUtils; import org.junit.Test; public class TestMemcachedCacheEntryFactoryImpl { @Test public void createsMemcachedCacheEntryImpls() { final String key = "key"; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); final MemcachedCacheEntryFactoryImpl impl = new MemcachedCacheEntryFactoryImpl(); final MemcachedCacheEntry result = impl.getMemcachedCacheEntry(key, entry); assertNotNull(result); assertSame(key, result.getStorageKey()); assertSame(entry, result.getHttpCacheEntry()); } } ././@LongLink0100644 0000000 0000000 00000000210 12302131606 011616 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcached/TestMemcachedCacheEntryImpl.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000010440 12301751716 032312 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.impl.client.cache.DefaultHttpCacheEntrySerializer; import org.apache.http.impl.client.cache.HttpTestUtils; import org.junit.Before; import org.junit.Test; public class TestMemcachedCacheEntryImpl { private MemcachedCacheEntryImpl impl; private HttpCacheEntry entry; @Before public void setUp() { entry = HttpTestUtils.makeCacheEntry(); impl = new MemcachedCacheEntryImpl("foo", entry); } @Test public void canBeCreatedEmpty() { impl = new MemcachedCacheEntryImpl(); assertNull(impl.getStorageKey()); assertNull(impl.getHttpCacheEntry()); } @Test public void canBeSerialized() { final byte[] bytes = impl.toByteArray(); assertNotNull(bytes); assertTrue(bytes.length > 0); } @Test public void knowsItsCacheKey() { assertEquals("foo", impl.getStorageKey()); } @Test public void knowsItsCacheEntry() { assertEquals(entry, impl.getHttpCacheEntry()); } @Test public void canBeReconstitutedFromByteArray() throws Exception { final String key = impl.getStorageKey(); final HttpCacheEntry entry = impl.getHttpCacheEntry(); final byte[] bytes = impl.toByteArray(); impl = new MemcachedCacheEntryImpl(); impl.set(bytes); assertEquals(key, impl.getStorageKey()); assertEquivalent(entry, impl.getHttpCacheEntry()); } @Test(expected=MemcachedSerializationException.class) public void cannotReconstituteFromGarbage() { impl = new MemcachedCacheEntryImpl(); final byte[] bytes = HttpTestUtils.getRandomBytes(128); impl.set(bytes); } private void assertEquivalent(final HttpCacheEntry entry, final HttpCacheEntry resultEntry) throws IOException { /* Ugh. Implementing HttpCacheEntry#equals is problematic * due to the Resource response body (may cause unexpected * I/O to users). Checking that two entries * serialize to the same bytes seems simpler, on the whole, * (while still making for a somewhat yucky test). At * least we encapsulate it off here in its own method so * the test that uses it remains clear. */ final DefaultHttpCacheEntrySerializer ser = new DefaultHttpCacheEntrySerializer(); final ByteArrayOutputStream bos1 = new ByteArrayOutputStream(); ser.writeTo(entry, bos1); final byte[] bytes1 = bos1.toByteArray(); final ByteArrayOutputStream bos2 = new ByteArrayOutputStream(); ser.writeTo(resultEntry, bos2); final byte[] bytes2 = bos2.toByteArray(); assertEquals(bytes1.length, bytes2.length); for(int i = 0; i < bytes1.length; i++) { assertEquals(bytes1[i], bytes2[i]); } } } ././@LongLink0100644 0000000 0000000 00000000212 12302131606 011620 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000057011 12301751716 032317 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; import java.io.IOException; import java.io.UnsupportedEncodingException; import junit.framework.TestCase; import net.spy.memcached.CASResponse; import net.spy.memcached.CASValue; import net.spy.memcached.MemcachedClientIF; import net.spy.memcached.OperationTimeoutException; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheUpdateCallback; import org.apache.http.client.cache.HttpCacheUpdateException; import org.apache.http.impl.client.cache.CacheConfig; import org.apache.http.impl.client.cache.HttpTestUtils; import org.easymock.EasyMock; import org.junit.Before; import org.junit.Test; public class TestMemcachedHttpCacheStorage extends TestCase { private MemcachedHttpCacheStorage impl; private MemcachedClientIF mockMemcachedClient; private KeyHashingScheme mockKeyHashingScheme; private MemcachedCacheEntryFactory mockMemcachedCacheEntryFactory; private MemcachedCacheEntry mockMemcachedCacheEntry; private MemcachedCacheEntry mockMemcachedCacheEntry2; private MemcachedCacheEntry mockMemcachedCacheEntry3; private MemcachedCacheEntry mockMemcachedCacheEntry4; @Override @Before public void setUp() throws Exception { mockMemcachedClient = EasyMock.createNiceMock(MemcachedClientIF.class); mockKeyHashingScheme = EasyMock.createNiceMock(KeyHashingScheme.class); mockMemcachedCacheEntryFactory = EasyMock.createNiceMock(MemcachedCacheEntryFactory.class); mockMemcachedCacheEntry = EasyMock.createNiceMock(MemcachedCacheEntry.class); mockMemcachedCacheEntry2 = EasyMock.createNiceMock(MemcachedCacheEntry.class); mockMemcachedCacheEntry3 = EasyMock.createNiceMock(MemcachedCacheEntry.class); mockMemcachedCacheEntry4 = EasyMock.createNiceMock(MemcachedCacheEntry.class); final CacheConfig config = CacheConfig.custom().setMaxUpdateRetries(1).build(); impl = new MemcachedHttpCacheStorage(mockMemcachedClient, config, mockMemcachedCacheEntryFactory, mockKeyHashingScheme); } private void replayMocks() { EasyMock.replay(mockMemcachedClient); EasyMock.replay(mockKeyHashingScheme); EasyMock.replay(mockMemcachedCacheEntry); EasyMock.replay(mockMemcachedCacheEntry2); EasyMock.replay(mockMemcachedCacheEntry3); EasyMock.replay(mockMemcachedCacheEntry4); EasyMock.replay(mockMemcachedCacheEntryFactory); } private void verifyMocks() { EasyMock.verify(mockMemcachedClient); EasyMock.verify(mockKeyHashingScheme); EasyMock.verify(mockMemcachedCacheEntry); EasyMock.verify(mockMemcachedCacheEntry2); EasyMock.verify(mockMemcachedCacheEntry3); EasyMock.verify(mockMemcachedCacheEntry4); EasyMock.verify(mockMemcachedCacheEntryFactory); } @Test public void testSuccessfulCachePut() throws IOException { final String url = "foo"; final String key = "key"; final HttpCacheEntry value = HttpTestUtils.makeCacheEntry(); final byte[] serialized = HttpTestUtils.getRandomBytes(128); EasyMock.expect(mockMemcachedCacheEntryFactory.getMemcachedCacheEntry(url, value)) .andReturn(mockMemcachedCacheEntry); EasyMock.expect(mockMemcachedCacheEntry.toByteArray()) .andReturn(serialized); EasyMock.expect(mockKeyHashingScheme.hash(url)) .andReturn(key); EasyMock.expect(mockMemcachedClient.set(key, 0, serialized)) .andReturn(null); replayMocks(); impl.putEntry(url, value); verifyMocks(); } @Test public void testCachePutFailsSilentlyWhenWeCannotHashAKey() throws IOException { final String url = "foo"; final HttpCacheEntry value = HttpTestUtils.makeCacheEntry(); final byte[] serialized = HttpTestUtils.getRandomBytes(128); EasyMock.expect(mockMemcachedCacheEntryFactory.getMemcachedCacheEntry(url, value)) .andReturn(mockMemcachedCacheEntry).times(0,1); EasyMock.expect(mockMemcachedCacheEntry.toByteArray()) .andReturn(serialized).times(0,1); EasyMock.expect(mockKeyHashingScheme.hash(url)) .andThrow(new MemcachedKeyHashingException(new Exception())); replayMocks(); impl.putEntry(url, value); verifyMocks(); } public void testThrowsIOExceptionWhenMemcachedPutTimesOut() { final String url = "foo"; final String key = "key"; final HttpCacheEntry value = HttpTestUtils.makeCacheEntry(); final byte[] serialized = HttpTestUtils.getRandomBytes(128); EasyMock.expect(mockMemcachedCacheEntryFactory.getMemcachedCacheEntry(url, value)) .andReturn(mockMemcachedCacheEntry); EasyMock.expect(mockMemcachedCacheEntry.toByteArray()) .andReturn(serialized); EasyMock.expect(mockKeyHashingScheme.hash(url)) .andReturn(key); EasyMock.expect(mockMemcachedClient.set(key, 0, serialized)) .andThrow(new OperationTimeoutException("timed out")); replayMocks(); try { impl.putEntry(url, value); fail("should have thrown exception"); } catch (final IOException expected) { } verifyMocks(); } @Test public void testCachePutThrowsIOExceptionIfCannotSerializeEntry() { final String url = "foo"; final String key = "key"; final HttpCacheEntry value = HttpTestUtils.makeCacheEntry(); EasyMock.expect(mockMemcachedCacheEntryFactory.getMemcachedCacheEntry(url, value)) .andReturn(mockMemcachedCacheEntry); EasyMock.expect(mockMemcachedCacheEntry.toByteArray()) .andThrow(new MemcachedSerializationException(new Exception())); EasyMock.expect(mockKeyHashingScheme.hash(url)) .andReturn(key).times(0,1); replayMocks(); try { impl.putEntry(url, value); fail("should have thrown exception"); } catch (final IOException expected) { } verifyMocks(); } @Test public void testSuccessfulCacheGet() throws UnsupportedEncodingException, IOException { final String url = "foo"; final String key = "key"; final byte[] serialized = HttpTestUtils.getRandomBytes(128); final HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(); EasyMock.expect(mockKeyHashingScheme.hash(url)).andReturn(key); EasyMock.expect(mockMemcachedClient.get(key)).andReturn(serialized); EasyMock.expect(mockMemcachedCacheEntryFactory.getUnsetCacheEntry()) .andReturn(mockMemcachedCacheEntry); mockMemcachedCacheEntry.set(serialized); EasyMock.expect(mockMemcachedCacheEntry.getStorageKey()).andReturn(url); EasyMock.expect(mockMemcachedCacheEntry.getHttpCacheEntry()).andReturn(cacheEntry); replayMocks(); final HttpCacheEntry resultingEntry = impl.getEntry(url); verifyMocks(); assertSame(cacheEntry, resultingEntry); } @Test public void testTreatsNoneByteArrayFromMemcachedAsCacheMiss() throws UnsupportedEncodingException, IOException { final String url = "foo"; final String key = "key"; EasyMock.expect(mockKeyHashingScheme.hash(url)).andReturn(key); EasyMock.expect(mockMemcachedClient.get(key)).andReturn(new Object()); replayMocks(); final HttpCacheEntry resultingEntry = impl.getEntry(url); verifyMocks(); assertNull(resultingEntry); } @Test public void testTreatsNullFromMemcachedAsCacheMiss() throws UnsupportedEncodingException, IOException { final String url = "foo"; final String key = "key"; EasyMock.expect(mockKeyHashingScheme.hash(url)).andReturn(key); EasyMock.expect(mockMemcachedClient.get(key)).andReturn(null); replayMocks(); final HttpCacheEntry resultingEntry = impl.getEntry(url); verifyMocks(); assertNull(resultingEntry); } @Test public void testTreatsAsCacheMissIfCannotReconstituteEntry() throws UnsupportedEncodingException, IOException { final String url = "foo"; final String key = "key"; final byte[] serialized = HttpTestUtils.getRandomBytes(128); EasyMock.expect(mockKeyHashingScheme.hash(url)).andReturn(key); EasyMock.expect(mockMemcachedClient.get(key)).andReturn(serialized); EasyMock.expect(mockMemcachedCacheEntryFactory.getUnsetCacheEntry()) .andReturn(mockMemcachedCacheEntry); mockMemcachedCacheEntry.set(serialized); EasyMock.expectLastCall().andThrow(new MemcachedSerializationException(new Exception())); replayMocks(); assertNull(impl.getEntry(url)); verifyMocks(); } @Test public void testTreatsAsCacheMissIfCantHashStorageKey() throws UnsupportedEncodingException, IOException { final String url = "foo"; EasyMock.expect(mockKeyHashingScheme.hash(url)).andThrow(new MemcachedKeyHashingException(new Exception())); replayMocks(); assertNull(impl.getEntry(url)); verifyMocks(); } @Test public void testThrowsIOExceptionIfMemcachedTimesOutOnGet() { final String url = "foo"; final String key = "key"; EasyMock.expect(mockKeyHashingScheme.hash(url)).andReturn(key); EasyMock.expect(mockMemcachedClient.get(key)) .andThrow(new OperationTimeoutException("")); replayMocks(); try { impl.getEntry(url); fail("should have thrown exception"); } catch (final IOException expected) { } verifyMocks(); } @Test public void testCacheRemove() throws IOException { final String url = "foo"; final String key = "key"; EasyMock.expect(mockKeyHashingScheme.hash(url)).andReturn(key); EasyMock.expect(mockMemcachedClient.delete(key)).andReturn(null); replayMocks(); impl.removeEntry(url); verifyMocks(); } @Test public void testCacheRemoveHandlesKeyHashingFailure() throws IOException { final String url = "foo"; EasyMock.expect(mockKeyHashingScheme.hash(url)).andReturn(null); replayMocks(); impl.removeEntry(url); verifyMocks(); } @Test public void testCacheRemoveThrowsIOExceptionOnMemcachedTimeout() { final String url = "foo"; final String key = "key"; EasyMock.expect(mockKeyHashingScheme.hash(url)).andReturn(key); EasyMock.expect(mockMemcachedClient.delete(key)) .andThrow(new OperationTimeoutException("")); replayMocks(); try { impl.removeEntry(url); fail("should have thrown exception"); } catch (final IOException expected) { } verifyMocks(); } @Test public void testCacheUpdateCanUpdateNullEntry() throws IOException, HttpCacheUpdateException { final String url = "foo"; final String key = "key"; final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); final byte[] serialized = HttpTestUtils.getRandomBytes(128); final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback() { public HttpCacheEntry update(final HttpCacheEntry old) { assertNull(old); return updatedValue; } }; // get empty old entry EasyMock.expect(mockKeyHashingScheme.hash(url)).andReturn(key).anyTimes(); EasyMock.expect(mockMemcachedClient.gets(key)).andReturn(null); EasyMock.expect(mockMemcachedCacheEntryFactory.getMemcachedCacheEntry(url, updatedValue)) .andReturn(mockMemcachedCacheEntry); EasyMock.expect(mockMemcachedCacheEntry.toByteArray()).andReturn(serialized); EasyMock.expect( mockMemcachedClient.set(EasyMock.eq(key), EasyMock.eq(0), EasyMock.aryEq(serialized))).andReturn(null); replayMocks(); impl.updateEntry(url, callback); verifyMocks(); } @Test public void testCacheUpdateOverwritesNonMatchingHashCollision() throws IOException, HttpCacheUpdateException { final String url = "foo"; final String key = "key"; final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); final byte[] oldBytes = HttpTestUtils.getRandomBytes(128); final CASValue casValue = new CASValue(-1, oldBytes); final byte[] newBytes = HttpTestUtils.getRandomBytes(128); final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback() { public HttpCacheEntry update(final HttpCacheEntry old) { assertNull(old); return updatedValue; } }; // get empty old entry EasyMock.expect(mockKeyHashingScheme.hash(url)).andReturn(key).anyTimes(); EasyMock.expect(mockMemcachedClient.gets(key)).andReturn(casValue); EasyMock.expect(mockMemcachedCacheEntryFactory.getUnsetCacheEntry()) .andReturn(mockMemcachedCacheEntry); mockMemcachedCacheEntry.set(oldBytes); EasyMock.expect(mockMemcachedCacheEntry.getStorageKey()).andReturn("not" + url).anyTimes(); EasyMock.expect(mockMemcachedCacheEntryFactory.getMemcachedCacheEntry(url, updatedValue)) .andReturn(mockMemcachedCacheEntry2); EasyMock.expect(mockMemcachedCacheEntry2.toByteArray()).andReturn(newBytes); EasyMock.expect( mockMemcachedClient.set(EasyMock.eq(key), EasyMock.eq(0), EasyMock.aryEq(newBytes))).andReturn(null); replayMocks(); impl.updateEntry(url, callback); verifyMocks(); } @Test public void testCacheUpdateCanUpdateExistingEntry() throws IOException, HttpCacheUpdateException { final String url = "foo"; final String key = "key"; final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); final byte[] oldBytes = HttpTestUtils.getRandomBytes(128); final CASValue casValue = new CASValue(1, oldBytes); final byte[] newBytes = HttpTestUtils.getRandomBytes(128); final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback() { public HttpCacheEntry update(final HttpCacheEntry old) { assertSame(existingValue, old); return updatedValue; } }; // get empty old entry EasyMock.expect(mockKeyHashingScheme.hash(url)).andReturn(key).anyTimes(); EasyMock.expect(mockMemcachedClient.gets(key)).andReturn(casValue); EasyMock.expect(mockMemcachedCacheEntryFactory.getUnsetCacheEntry()) .andReturn(mockMemcachedCacheEntry); mockMemcachedCacheEntry.set(oldBytes); EasyMock.expect(mockMemcachedCacheEntry.getStorageKey()).andReturn(url); EasyMock.expect(mockMemcachedCacheEntry.getHttpCacheEntry()).andReturn(existingValue); EasyMock.expect(mockMemcachedCacheEntryFactory.getMemcachedCacheEntry(url, updatedValue)) .andReturn(mockMemcachedCacheEntry2); EasyMock.expect(mockMemcachedCacheEntry2.toByteArray()).andReturn(newBytes); EasyMock.expect( mockMemcachedClient.cas(EasyMock.eq(key), EasyMock.eq(casValue.getCas()), EasyMock.aryEq(newBytes))).andReturn(CASResponse.OK); replayMocks(); impl.updateEntry(url, callback); verifyMocks(); } @Test public void testCacheUpdateThrowsExceptionsIfCASFailsEnoughTimes() throws IOException { final String url = "foo"; final String key = "key"; final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); final byte[] oldBytes = HttpTestUtils.getRandomBytes(128); final CASValue casValue = new CASValue(1, oldBytes); final byte[] newBytes = HttpTestUtils.getRandomBytes(128); final CacheConfig config = CacheConfig.custom().setMaxUpdateRetries(0).build(); impl = new MemcachedHttpCacheStorage(mockMemcachedClient, config, mockMemcachedCacheEntryFactory, mockKeyHashingScheme); final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback() { public HttpCacheEntry update(final HttpCacheEntry old) { assertSame(existingValue, old); return updatedValue; } }; // get empty old entry EasyMock.expect(mockKeyHashingScheme.hash(url)).andReturn(key).anyTimes(); EasyMock.expect(mockMemcachedClient.gets(key)).andReturn(casValue); EasyMock.expect(mockMemcachedCacheEntryFactory.getUnsetCacheEntry()) .andReturn(mockMemcachedCacheEntry); mockMemcachedCacheEntry.set(oldBytes); EasyMock.expect(mockMemcachedCacheEntry.getStorageKey()).andReturn(url); EasyMock.expect(mockMemcachedCacheEntry.getHttpCacheEntry()).andReturn(existingValue); EasyMock.expect(mockMemcachedCacheEntryFactory.getMemcachedCacheEntry(url, updatedValue)) .andReturn(mockMemcachedCacheEntry2); EasyMock.expect(mockMemcachedCacheEntry2.toByteArray()).andReturn(newBytes); EasyMock.expect( mockMemcachedClient.cas(EasyMock.eq(key), EasyMock.eq(casValue.getCas()), EasyMock.aryEq(newBytes))).andReturn(CASResponse.EXISTS); replayMocks(); try { impl.updateEntry(url, callback); fail("should have thrown exception"); } catch (final HttpCacheUpdateException expected) { } verifyMocks(); } @Test public void testCacheUpdateCanUpdateExistingEntryWithRetry() throws IOException, HttpCacheUpdateException { final String url = "foo"; final String key = "key"; final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry existingValue2 = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry updatedValue2 = HttpTestUtils.makeCacheEntry(); final byte[] oldBytes = HttpTestUtils.getRandomBytes(128); final byte[] oldBytes2 = HttpTestUtils.getRandomBytes(128); final CASValue casValue = new CASValue(1, oldBytes); final CASValue casValue2 = new CASValue(2, oldBytes2); final byte[] newBytes = HttpTestUtils.getRandomBytes(128); final byte[] newBytes2 = HttpTestUtils.getRandomBytes(128); final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback() { public HttpCacheEntry update(final HttpCacheEntry old) { if (old == existingValue) { return updatedValue; } assertSame(existingValue2, old); return updatedValue2; } }; EasyMock.expect(mockKeyHashingScheme.hash(url)).andReturn(key).anyTimes(); EasyMock.expect(mockMemcachedClient.gets(key)).andReturn(casValue); EasyMock.expect(mockMemcachedCacheEntryFactory.getUnsetCacheEntry()) .andReturn(mockMemcachedCacheEntry); mockMemcachedCacheEntry.set(oldBytes); EasyMock.expect(mockMemcachedCacheEntry.getStorageKey()).andReturn(url); EasyMock.expect(mockMemcachedCacheEntry.getHttpCacheEntry()).andReturn(existingValue); EasyMock.expect(mockMemcachedCacheEntryFactory.getMemcachedCacheEntry(url, updatedValue)) .andReturn(mockMemcachedCacheEntry2); EasyMock.expect(mockMemcachedCacheEntry2.toByteArray()).andReturn(newBytes); EasyMock.expect( mockMemcachedClient.cas(EasyMock.eq(key), EasyMock.eq(casValue.getCas()), EasyMock.aryEq(newBytes))).andReturn(CASResponse.EXISTS); // take two EasyMock.expect(mockMemcachedClient.gets(key)).andReturn(casValue2); EasyMock.expect(mockMemcachedCacheEntryFactory.getUnsetCacheEntry()) .andReturn(mockMemcachedCacheEntry3); mockMemcachedCacheEntry3.set(oldBytes2); EasyMock.expect(mockMemcachedCacheEntry3.getStorageKey()).andReturn(url); EasyMock.expect(mockMemcachedCacheEntry3.getHttpCacheEntry()).andReturn(existingValue2); EasyMock.expect(mockMemcachedCacheEntryFactory.getMemcachedCacheEntry(url, updatedValue2)) .andReturn(mockMemcachedCacheEntry4); EasyMock.expect(mockMemcachedCacheEntry4.toByteArray()).andReturn(newBytes2); EasyMock.expect( mockMemcachedClient.cas(EasyMock.eq(key), EasyMock.eq(casValue2.getCas()), EasyMock.aryEq(newBytes2))).andReturn(CASResponse.OK); replayMocks(); impl.updateEntry(url, callback); verifyMocks(); } @Test public void testUpdateThrowsIOExceptionIfMemcachedTimesOut() throws HttpCacheUpdateException { final String url = "foo"; final String key = "key"; final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback() { public HttpCacheEntry update(final HttpCacheEntry old) { assertNull(old); return updatedValue; } }; // get empty old entry EasyMock.expect(mockKeyHashingScheme.hash(url)).andReturn(key).anyTimes(); EasyMock.expect(mockMemcachedClient.gets(key)) .andThrow(new OperationTimeoutException("")); replayMocks(); try { impl.updateEntry(url, callback); fail("should have thrown exception"); } catch (final IOException expected) { } verifyMocks(); } @Test(expected=HttpCacheUpdateException.class) public void testThrowsExceptionOnUpdateIfCannotHashStorageKey() throws Exception { final String url = "foo"; EasyMock.expect(mockKeyHashingScheme.hash(url)) .andThrow(new MemcachedKeyHashingException(new Exception())); replayMocks(); try { impl.updateEntry(url, null); fail("should have thrown exception"); } catch (final HttpCacheUpdateException expected) { } verifyMocks(); } } ././@LongLink0100644 0000000 0000000 00000000207 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcached/TestPrefixKeyHashingScheme.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000003667 12301751716 032327 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; public class TestPrefixKeyHashingScheme { private static final String KEY = "key"; private static final String PREFIX = "prefix"; private PrefixKeyHashingScheme impl; private KeyHashingScheme scheme; @Before public void setUp() { scheme = new KeyHashingScheme() { public String hash(final String storageKey) { assertEquals(KEY, storageKey); return "hash"; } }; impl = new PrefixKeyHashingScheme(PREFIX, scheme); } @Test public void addsPrefixToBackingScheme() { assertEquals("prefixhash", impl.hash(KEY)); } } ././@LongLink0100644 0000000 0000000 00000000204 12302131606 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcached/TestSHA256HashingScheme.javahttpcomponents-client-4.3.3/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcach0100644 0000000 0000000 00000003070 12301751716 032313 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.client.cache.memcached; import static org.junit.Assert.assertTrue; import org.junit.Test; public class TestSHA256HashingScheme { @Test public void canHash() { final SHA256KeyHashingScheme impl = new SHA256KeyHashingScheme(); final String result = impl.hash("hello, hashing world"); assertTrue(result != null && result.length() > 0); } } httpcomponents-client-4.3.3/httpclient-cache/src/test/resources/0040755 0000000 0000000 00000000000 12301751716 023616 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-cache/src/test/resources/commons-logging.properties0100644 0000000 0000000 00000002350 12301751716 031030 0ustar000000000 0000000 # ==================================================================== # 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. # ==================================================================== # # This software consists of voluntary contributions made by many # individuals on behalf of the Apache Software Foundation. For more # information on the Apache Software Foundation, please see # . # Disable logging for unit tests org.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog httpcomponents-client-4.3.3/httpclient-osgi/0040755 0000000 0000000 00000000000 12301753040 017724 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/pom.xml0100644 0000000 0000000 00000017426 12301751652 021257 0ustar000000000 0000000 4.0.0 org.apache.httpcomponents httpcomponents-client 4.3.3 httpclient-osgi Apache HttpClient OSGi bundle 1999 HttpComponents Client (OSGi bundle) http://hc.apache.org/httpcomponents-client bundle "[4.3.0, 4.4.0)" "[1.1.0, 1.2.0)" org.apache.httpcomponents httpclient ${project.version} compile org.apache.httpcomponents httpcore compile commons-codec commons-codec ${commons-codec.version} compile org.apache.httpcomponents httpmime ${project.version} compile org.apache.httpcomponents httpclient-cache ${project.version} compile org.apache.httpcomponents fluent-hc ${project.version} compile org.osgi org.osgi.core 4.2.0 provided org.osgi org.osgi.compendium 4.2.0 provided junit junit test src/main/resources org.apache.felix maven-bundle-plugin true Apache ${project.name} ${project.groupId}.httpclient <_exportcontents> org.apache.http.auth.*;version=${project.version}, org.apache.http.cookie.*;version=${project.version}, org.apache.http.conn.*;version=${project.version}, org.apache.http.client.*;version=${project.version}, org.apache.http.entity.mime.*;version=${project.version}, org.apache.http.impl.auth.*;version=${project.version}, org.apache.http.impl.cookie.*;version=${project.version}, org.apache.http.impl.conn.*;version=${project.version}, org.apache.http.impl.execchain.*;version=${project.version}, org.apache.http.impl.client.*;version=${project.version}, org.apache.http.osgi.services.*;version=${project.version} *;scope=compile|runtime;inline=true javax.crypto, javax.crypto.spec, javax.net, javax.net.ssl, javax.security.auth.x500, org.ietf.jgss,, org.osgi.framework, org.osgi.service.cm, org.apache.commons.logging;version=${commons-logging.osgi.import.version}, org.apache.http;version=${httpcore.osgi.import.version}, org.apache.http.config;version=${httpcore.osgi.import.version}, org.apache.http.concurrent;version=${httpcore.osgi.import.version}, org.apache.http.entity;version=${httpcore.osgi.import.version}, org.apache.http.io;version=${httpcore.osgi.import.version}, org.apache.http.message;version=${httpcore.osgi.import.version}, org.apache.http.params;version=${httpcore.osgi.import.version}, org.apache.http.pool;version=${httpcore.osgi.import.version}, org.apache.http.protocol;version=${httpcore.osgi.import.version}, org.apache.http.util;version=${httpcore.osgi.import.version}, org.apache.http.impl;version=${httpcore.osgi.import.version}, org.apache.http.impl.entity;version=${httpcore.osgi.import.version}, org.apache.http.impl.io;version=${httpcore.osgi.import.version}, org.apache.http.impl.pool;version=${httpcore.osgi.import.version}, net.sf.ehcache.*;resolution:=optional, net.spy.memcached.*;resolution:=optional org.apache.http.osgi.impl.HttpProxyConfigurationActivator <_removeheaders>JAVA_1_3_HOME,JAVA_1_4_HOME org.codehaus.mojo clirr-maven-plugin true org.apache.httpcomponents.httpclient_${project.version} maven-project-info-reports-plugin ${hc.project-info.version} false dependencies dependency-info summary httpcomponents-client-4.3.3/httpclient-osgi/src/0040755 0000000 0000000 00000000000 12301751651 020521 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/0040755 0000000 0000000 00000000000 12301751651 021445 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/0040755 0000000 0000000 00000000000 12301751651 022366 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/0040755 0000000 0000000 00000000000 12301751651 023155 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/0040755 0000000 0000000 00000000000 12301751651 024376 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/0040755 0000000 0000000 00000000000 12301751651 025355 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/0040755 0000000 0000000 00000000000 12301751652 026317 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/package-info.java0100644 0000000 0000000 00000002325 12301751652 031505 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * @since 4.3 */ package org.apache.http.osgi; httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/0040755 0000000 0000000 00000000000 12301751652 027260 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000171 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/HttpProxyConfigurationActivator.javahttpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/HttpProxyConfigu0100644 0000000 0000000 00000014001 12301751652 032470 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.osgi.impl; import java.io.Closeable; import java.io.IOException; import java.util.Dictionary; import java.util.Hashtable; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.osgi.services.HttpClientBuilderFactory; import org.apache.http.osgi.services.ProxyConfiguration; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedServiceFactory; /** * @since 4.3 */ public final class HttpProxyConfigurationActivator implements BundleActivator, ManagedServiceFactory { private static final String SERVICE_FACTORY_NAME = "Apache HTTP Client Proxy Configuration Factory"; private static final String SERVICE_PID = "org.apache.http.proxyconfigurator"; private ServiceRegistration configurator; private ServiceRegistration clientFactory; private BundleContext context; private final Map registeredConfigurations = new LinkedHashMap(); private final List trackedHttpClients = new LinkedList(); /** * {@inheritDoc} */ public void start(final BundleContext context) throws Exception { this.context = context; // ensure we receive configurations for the proxy selector final Hashtable props = new Hashtable(); props.put(Constants.SERVICE_PID, getName()); props.put(Constants.SERVICE_VENDOR, context.getBundle().getHeaders(Constants.BUNDLE_VENDOR)); props.put(Constants.SERVICE_DESCRIPTION, SERVICE_FACTORY_NAME); configurator = context.registerService(ManagedServiceFactory.class.getName(), this, props); clientFactory = context.registerService(HttpClientBuilderFactory.class.getName(), new OSGiClientBuilderFactory(context, registeredConfigurations, trackedHttpClients), props); } /** * {@inheritDoc} */ public void stop(final BundleContext context) throws Exception { // unregister services for (final ServiceRegistration registeredConfiguration : registeredConfigurations.values()) { registeredConfiguration.unregister(); } // unregister service factory if (configurator != null) { configurator.unregister(); } if (clientFactory != null) { clientFactory.unregister(); } // ensure all http clients - generated with the - are terminated for (final CloseableHttpClient client : trackedHttpClients) { if (null != client) { closeQuietly(client); } } // remove all tracked services registeredConfigurations.clear(); // remove all tracked created clients trackedHttpClients.clear(); } /** * {@inheritDoc} */ public String getName() { return SERVICE_PID; } /** * {@inheritDoc} */ public void updated(final String pid, @SuppressWarnings("rawtypes") final Dictionary config) throws ConfigurationException { final ServiceRegistration registration = registeredConfigurations.get(pid); OSGiProxyConfiguration proxyConfiguration; if (registration == null) { proxyConfiguration = new OSGiProxyConfiguration(); final ServiceRegistration configurationRegistration = context.registerService(ProxyConfiguration.class.getName(), proxyConfiguration, config); registeredConfigurations.put(pid, configurationRegistration); } else { proxyConfiguration = (OSGiProxyConfiguration) context.getService(registration.getReference()); } @SuppressWarnings("unchecked") // data type is known final Dictionary properties = config; proxyConfiguration.update(properties); } /** * {@inheritDoc} */ public void deleted(final String pid) { final ServiceRegistration registeredConfiguration = registeredConfigurations.get(pid); if (null != registeredConfiguration) { registeredConfiguration.unregister(); registeredConfigurations.remove(pid); } } private static void closeQuietly(final Closeable closeable) { try { closeable.close(); } catch (final IOException e) { // do nothing } } } ././@LongLink0100644 0000000 0000000 00000000162 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/OSGiClientBuilderFactory.javahttpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/OSGiClientBuilde0100644 0000000 0000000 00000004512 12301751652 032267 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.osgi.impl; import java.util.List; import java.util.Map; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.osgi.services.HttpClientBuilderFactory; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; /** * @since 4.3 */ public final class OSGiClientBuilderFactory implements HttpClientBuilderFactory { private final BundleContext bundleContext; private final Map registeredConfigurations; private final List trackedHttpClients; public OSGiClientBuilderFactory( final BundleContext bundleContext, final Map registeredConfigurations, final List trackedHttpClients) { this.bundleContext = bundleContext; this.registeredConfigurations = registeredConfigurations; this.trackedHttpClients = trackedHttpClients; } public HttpClientBuilder newBuilder() { return new OSGiHttpClientBuilder(bundleContext, registeredConfigurations, trackedHttpClients); } } ././@LongLink0100644 0000000 0000000 00000000161 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/OSGiCredentialsProvider.javahttpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/OSGiCredentialsP0100644 0000000 0000000 00000006652 12301751652 032310 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.osgi.impl; import java.util.Map; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.osgi.services.ProxyConfiguration; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; /** * @since 4.3 */ final class OSGiCredentialsProvider implements CredentialsProvider { private final BundleContext bundleContext; private final Map registeredConfigurations; public OSGiCredentialsProvider( final BundleContext bundleContext, final Map registeredConfigurations) { this.bundleContext = bundleContext; this.registeredConfigurations = registeredConfigurations; } /** * {@inheritDoc} */ public void setCredentials(final AuthScope authscope, final Credentials credentials) { // do nothing, not used in this version } /** * {@inheritDoc} */ public Credentials getCredentials(final AuthScope authscope) { // iterate over all active proxy configurations at the moment of getting the credential for (final ServiceRegistration registration : registeredConfigurations.values()) { final Object proxyConfigurationObject = bundleContext.getService(registration.getReference()); if (proxyConfigurationObject != null) { final ProxyConfiguration proxyConfiguration = (ProxyConfiguration) proxyConfigurationObject; if (proxyConfiguration.isEnabled()) { final AuthScope actual = new AuthScope(proxyConfiguration.getHostname(), proxyConfiguration.getPort()); if (authscope.equals(actual)) { return new UsernamePasswordCredentials(proxyConfiguration.getUsername(), proxyConfiguration.getPassword()); } } } } // credentials no longer available! return null; } /** * {@inheritDoc} */ public void clear() { // do nothing, not used in this version } } ././@LongLink0100644 0000000 0000000 00000000157 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/OSGiHttpClientBuilder.javahttpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/OSGiHttpClientBu0100644 0000000 0000000 00000004434 12301751652 032274 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.osgi.impl; import java.util.List; import java.util.Map; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; /** * @since 4.3 */ final class OSGiHttpClientBuilder extends HttpClientBuilder { private final List trackedHttpClients; public OSGiHttpClientBuilder( final BundleContext bundleContext, final Map registeredConfigurations, final List trackedHttpClients) { this.trackedHttpClients = trackedHttpClients; setDefaultCredentialsProvider( new OSGiCredentialsProvider(bundleContext, registeredConfigurations)); setRoutePlanner( new OSGiHttpRoutePlanner(bundleContext, registeredConfigurations)); } @Override public CloseableHttpClient build() { final CloseableHttpClient httpClient = super.build(); trackedHttpClients.add(httpClient); return httpClient; } } ././@LongLink0100644 0000000 0000000 00000000156 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/OSGiHttpRoutePlanner.javahttpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/OSGiHttpRoutePla0100644 0000000 0000000 00000015655 12301751652 032331 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.osgi.impl; import java.util.Locale; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.impl.conn.DefaultRoutePlanner; import org.apache.http.osgi.services.ProxyConfiguration; import org.apache.http.protocol.HttpContext; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; /** * @since 4.3 */ final class OSGiHttpRoutePlanner extends DefaultRoutePlanner { private static final String DOT = "."; /** * The IP mask pattern against which hosts are matched. */ public static final Pattern IP_MASK_PATTERN = Pattern.compile("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"); private final BundleContext bundleContext; private final Map registeredConfigurations; public OSGiHttpRoutePlanner( final BundleContext bundleContext, final Map registeredConfigurations) { super(null); this.bundleContext = bundleContext; this.registeredConfigurations = registeredConfigurations; } /** * {@inheritDoc} */ @Override protected HttpHost determineProxy(final HttpHost target, final HttpRequest request, final HttpContext context) throws HttpException { ProxyConfiguration proxyConfiguration = null; for (final ServiceRegistration registration : registeredConfigurations.values()) { final Object proxyConfigurationObject = bundleContext.getService(registration.getReference()); if (proxyConfigurationObject != null) { proxyConfiguration = (ProxyConfiguration) proxyConfigurationObject; if (proxyConfiguration.isEnabled()) { for (final String exception : proxyConfiguration.getProxyExceptions()) { if (createMatcher(exception).matches(target.getHostName())) { return null; } else { return new HttpHost(proxyConfiguration.getHostname(), proxyConfiguration.getPort()); } } } } } return null; } private static HostMatcher createMatcher(final String name) { final NetworkAddress na = NetworkAddress.parse(name); if (na != null) { return new IPAddressMatcher(na); } if (name.startsWith(DOT)) { return new DomainNameMatcher(name); } return new HostNameMatcher(name); } private static interface HostMatcher { boolean matches(String host); } private static class HostNameMatcher implements HostMatcher { private final String hostName; HostNameMatcher(final String hostName) { this.hostName = hostName; } public boolean matches(final String host) { return hostName.equalsIgnoreCase(host); } } private static class DomainNameMatcher implements HostMatcher { private final String domainName; DomainNameMatcher(final String domainName) { this.domainName = domainName.toLowerCase(Locale.ENGLISH); } public boolean matches(final String host) { return host.toLowerCase(Locale.ENGLISH).endsWith(domainName); } } private static class IPAddressMatcher implements HostMatcher { private final NetworkAddress address; IPAddressMatcher(final NetworkAddress address) { this.address = address; } public boolean matches(final String host) { final NetworkAddress hostAddress = NetworkAddress.parse(host); return hostAddress != null && address.address == (hostAddress.address & address.mask); } } private static class NetworkAddress { final int address; final int mask; static NetworkAddress parse(final String adrSpec) { if (null != adrSpec) { final Matcher nameMatcher = IP_MASK_PATTERN.matcher(adrSpec); if (nameMatcher.matches()) { try { final int i1 = toInt(nameMatcher.group(1), 255); final int i2 = toInt(nameMatcher.group(2), 255); final int i3 = toInt(nameMatcher.group(3), 255); final int i4 = toInt(nameMatcher.group(4), 255); final int ip = i1 << 24 | i2 << 16 | i3 << 8 | i4; int mask = toInt(nameMatcher.group(6), 32); mask = (mask == 32) ? -1 : -1 - (-1 >>> mask); return new NetworkAddress(ip, mask); } catch (final NumberFormatException nfe) { // not expected after the pattern match ! } } } return null; } private static int toInt(final String value, final int max) { if (value == null || value.length() == 0) { return max; } int number = Integer.parseInt(value); if (number > max) { number = max; } return number; } NetworkAddress(final int address, final int mask) { this.address = address; this.mask = mask; } } } ././@LongLink0100644 0000000 0000000 00000000160 12302131606 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/OSGiProxyConfiguration.javahttpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/OSGiProxyConfigu0100644 0000000 0000000 00000011143 12301751652 032356 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.osgi.impl; import static java.lang.String.format; import static org.apache.http.osgi.impl.PropertiesUtils.to; import java.util.Dictionary; import org.apache.http.osgi.services.ProxyConfiguration; /** * @since 4.3 */ public final class OSGiProxyConfiguration implements ProxyConfiguration { /** * Property indicating whether this particular proxy is enabled (shall be used or not). Defaults to true. */ private static final String PROPERTYNAME_PROXY_ENABLED = "proxy.enabled"; private static final boolean PROPERTYDEFAULT_PROXY_ENABLED = true; /** * Property representing the hostname of the proxy. Defaults to empty. */ private static final String PROPERTYNAME_PROXY_HOSTNAME = "proxy.host"; private static final String PROPERTYDEFAULT_PROXY_HOSTNAME = ""; /** * Property representing the port of the proxy. Defaults to 0. */ private static final String PROPERTYNAME_PROXY_PORT = "proxy.port"; private static final int PROPERTYDEFAULT_PROXY_PORT = 0; /** * Property representing the username to authenticate with towards the proxy. Defaults to empty. */ private static final String PROPERTYNAME_PROXY_USERNAME = "proxy.username"; private static final String PROPERTYDEFAULT_PROXY_USERNAME = ""; /** * Property representing the password to authenticate with towards the proxy. Defaults to empty. */ private static final String PROPERTYNAME_PROXY_PASSWORD = "proxy.password"; private static final String PROPERTYDEFAULT_PROXY_PASSWORD = ""; /** * A multivalue property representing host patterns for which no proxy shall be used. By default localhost is * excluded. */ private static final String PROPERTYNAME_PROXY_EXCEPTIONS = "proxy.exceptions"; private static final String[] PROPERTYDEFAULT_PROXY_EXCEPTIONS = new String[]{"localhost", "127.0.0.1"}; private boolean enabled; private String hostname; private int port; private String username; private String password; private String[] proxyExceptions; public boolean isEnabled() { return enabled; } public String getHostname() { return hostname; } public int getPort() { return port; } public String getUsername() { return username; } public String getPassword() { return password; } public String[] getProxyExceptions() { return proxyExceptions; } public void update(final Dictionary config) { enabled = to(config.get(PROPERTYNAME_PROXY_ENABLED), boolean.class, PROPERTYDEFAULT_PROXY_ENABLED); hostname = to(config.get(PROPERTYNAME_PROXY_HOSTNAME), String.class, PROPERTYDEFAULT_PROXY_HOSTNAME); port = to(config.get(PROPERTYNAME_PROXY_PORT), int.class, PROPERTYDEFAULT_PROXY_PORT); username = to(config.get(PROPERTYNAME_PROXY_USERNAME), String.class, PROPERTYDEFAULT_PROXY_USERNAME); password = to(config.get(PROPERTYNAME_PROXY_PASSWORD), String.class, PROPERTYDEFAULT_PROXY_PASSWORD); proxyExceptions = to(config.get(PROPERTYNAME_PROXY_EXCEPTIONS), String[].class, PROPERTYDEFAULT_PROXY_EXCEPTIONS); } @Override public String toString() { return format("ProxyConfiguration [enabled=%s, hostname=%s, port=%s, username=%s, password=%s, proxyExceptions=%s]", proxyExceptions, enabled, hostname, port, username, password, proxyExceptions); } } ././@LongLink0100644 0000000 0000000 00000000146 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/package-info.javahttpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/package-info.jav0100644 0000000 0000000 00000002303 12301751652 032301 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.osgi.impl; ././@LongLink0100644 0000000 0000000 00000000151 12302131606 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/PropertiesUtils.javahttpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/impl/PropertiesUtils.0100644 0000000 0000000 00000015113 12301751652 032434 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.osgi.impl; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @since 4.3 */ final class PropertiesUtils { private static final Map, PropertyConverter> CONVERTERS_REGISTRY = new HashMap, PropertiesUtils.PropertyConverter>(); static { register(new BooleanPropertyConverter(), boolean.class, Boolean.class); register(new StringPropertyConverter(), String.class); register(new StringArrayPropertyConverter(), String[].class); register(new IntegerPropertyConverter(), int.class, Integer.class); register(new LongPropertyConverter(), long.class, Long.class); register(new DoublePropertyConverter(), double.class, Double.class); } private static void register(final PropertyConverter converter, final Class...targetTypes) { for (final Class targetType : targetTypes) { CONVERTERS_REGISTRY.put(targetType, converter); } } public static T to(final Object propValue, final Class targetType, final T defaultValue) { Object v = propValue; if (v == null) { return defaultValue; } if (!targetType.isArray()) { v = toObject(v); } if (targetType.isInstance(v)) { return targetType.cast(v); } if (CONVERTERS_REGISTRY.containsKey(targetType)) { @SuppressWarnings("unchecked") final // type driven by targetType PropertyConverter converter = (PropertyConverter) CONVERTERS_REGISTRY.get(targetType); try { return converter.to(v); } catch (final Exception ignore) { } } return defaultValue; } /** * Returns the parameter as a single value. If the * parameter is neither an array nor a java.util.Collection the * parameter is returned unmodified. If the parameter is a non-empty array, * the first array element is returned. If the property is a non-empty * java.util.Collection, the first collection element is returned. * * @param propValue the parameter to convert. */ private static Object toObject(final Object propValue) { if (propValue.getClass().isArray()) { final Object[] prop = (Object[]) propValue; return prop.length > 0 ? prop[0] : null; } if (propValue instanceof Collection) { final Collection prop = (Collection) propValue; return prop.isEmpty() ? null : prop.iterator().next(); } return propValue; } /** * Hidden constructor, this class must not be instantiated. */ private PropertiesUtils() { // do nothing } private static interface PropertyConverter { T to(Object propValue); } private static class BooleanPropertyConverter implements PropertyConverter { public Boolean to(final Object propValue) { return Boolean.valueOf(String.valueOf(propValue)); } } private static class StringPropertyConverter implements PropertyConverter { public String to(final Object propValue) { return String.valueOf(propValue); } } private static class StringArrayPropertyConverter implements PropertyConverter { public String[] to(final Object propValue) { if (propValue instanceof String) { // single string return new String[] { (String) propValue }; } if (propValue.getClass().isArray()) { // other array final Object[] valueArray = (Object[]) propValue; final List values = new ArrayList(valueArray.length); for (final Object value : valueArray) { if (value != null) { values.add(value.toString()); } } return values.toArray(new String[values.size()]); } if (propValue instanceof Collection) { // collection final Collection valueCollection = (Collection) propValue; final List valueList = new ArrayList(valueCollection.size()); for (final Object value : valueCollection) { if (value != null) { valueList.add(value.toString()); } } return valueList.toArray(new String[valueList.size()]); } // don't care, fall through to default value throw new IllegalArgumentException(); } } private static class IntegerPropertyConverter implements PropertyConverter { public Integer to(final Object propValue) { return Integer.valueOf(String.valueOf(propValue)); } } private static class LongPropertyConverter implements PropertyConverter { public Long to(final Object propValue) { return Long.valueOf(String.valueOf(propValue)); } } private static class DoublePropertyConverter implements PropertyConverter { public Double to(final Object propValue) { return Double.valueOf(String.valueOf(propValue)); } } } httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/services/0040755 0000000 0000000 00000000000 12301751652 030142 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000166 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/services/HttpClientBuilderFactory.javahttpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/services/HttpClientBu0100644 0000000 0000000 00000002551 12301751652 032432 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.osgi.services; import org.apache.http.impl.client.HttpClientBuilder; /** * @since 4.3 */ public interface HttpClientBuilderFactory { HttpClientBuilder newBuilder(); } ././@LongLink0100644 0000000 0000000 00000000152 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/services/package-info.javahttpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/services/package-info0100644 0000000 0000000 00000002336 12301751652 032412 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * @since 4.3 */ package org.apache.http.osgi.services; ././@LongLink0100644 0000000 0000000 00000000160 12302131606 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/services/ProxyConfiguration.javahttpcomponents-client-4.3.3/httpclient-osgi/src/main/java/org/apache/http/osgi/services/ProxyConfigu0100644 0000000 0000000 00000002652 12301751652 032523 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.osgi.services; /** * @since 4.3 */ public interface ProxyConfiguration { boolean isEnabled(); String getHostname(); int getPort(); String getUsername(); String getPassword(); String[] getProxyExceptions(); } httpcomponents-client-4.3.3/httpclient-osgi/src/main/resources/0040755 0000000 0000000 00000000000 12301751651 023457 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/resources/OSGI-INF/0040755 0000000 0000000 00000000000 12301751651 024632 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/resources/OSGI-INF/metatype/0040755 0000000 0000000 00000000000 12301751651 026462 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000145 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/main/resources/OSGI-INF/metatype/metatype.propertieshttpcomponents-client-4.3.3/httpclient-osgi/src/main/resources/OSGI-INF/metatype/metatype.properties0100644 0000000 0000000 00000010172 12301751651 032426 0ustar000000000 0000000 # # 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. # proxyconfigurator.name = Apache HTTP Components Proxy Configurator proxyconfigurator.description = Factory configuration for transparent proxies used by every HTTP Client. proxyconfig.name = Apache HTTP Components Proxy Configuration proxyconfig.description = Proxy configuration for central and transparent proxying of http client connections. proxy.enabled.name = Enable HTTP Proxy proxy.enabled.description = Whether to enable or disable this particular proxy configuration. \ The default value is false. proxy.host.name = HTTP Proxy Host proxy.host.description = Host name (or IP Address) of the HTTP Proxy. This property is ignored if \ this proxy configuration is disabled. This property does not have a default value. Enabling \ this proxy but not setting the HTTP Proxy Host effectively disables this configuration. proxy.port.name = HTTP Proxy Port proxy.port.description = TCP port of the HTTP Proxy. This property is ignored if \ this proxy configuration is disabled. This property does not have a default value. Enabling \ this proxy but not setting the HTTP Proxy Port effectively disables this configuration. proxy.user.name = HTTP Proxy User proxy.user.description = The name of the user to authenticate as with the HTTP \ Proxy Host. If this field is empty, the proxy is considered to not be \ authenticated. The default is empty. This property is ignored if proxying is \ disabled or the proxy host is not properly configured. proxy.password.name = HTTP Proxy Password proxy.password.description = The password of the HTTP Proxy user to authenticate \ with. The default is empty. This property is ignored if proxying is \ disabled or the proxy host is not properly configured. proxy.ntlm.host.name = HTTP Proxy NTLM Host proxy.ntlm.host.description = The host the authentication request is \ originating from. Essentially, the computer name for this machine. By default \ the credentials assume simple username password authentication. If the proxy \ happens to be a Microsoft IIS Server using NTLM authentication this property \ must be set to the NT Domain name of the user to authenticate as. This is \ not set by default. proxy.ntlm.domain.name = HTTP Proxy NTLM Domain proxy.ntlm.domain.description = The NTLM domain to authenticate within. By \ default the credentials assume simple username password authentication. If \ the proxy happens to be a Microsoft IIS Server using NTLM authentication this \ property must be set to the NT Domain name of the user to authenticate as. \ This is not set by default. proxy.exceptions.name = No Proxy For proxy.exceptions.description = Lists domain names, host names, IP Addresses or \ or network addresses for which this proxy configuration should not be used. A domain \ name indicating all hosts of a domain is indicated by a leading dot, e.g. \ ".day.com". A network address is indicated with subnet mask notation indicating \ the number of bits make up the network address, e.g 192.168.1.0/24 means the \ class C network "192.168.1". Note that for proxy selection, the host name of \ URL is not resolved but directly compared to the list of exceptions. For this \ reason you might want to indicate both the network address and the domain for \ targets which should not be passed through the proxy. This property has no \ effect if this proxy configuration is disabled. The default value is [ localhost, \ 127.0.0.1 ].httpcomponents-client-4.3.3/httpclient-osgi/src/main/resources/OSGI-INF/metatype/metatype.xml0100644 0000000 0000000 00000004743 12301751651 031041 0ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/test/0040755 0000000 0000000 00000000000 12301751651 021500 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/test/java/0040755 0000000 0000000 00000000000 12301751651 022421 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/test/java/org/0040755 0000000 0000000 00000000000 12301751651 023210 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/test/java/org/apache/0040755 0000000 0000000 00000000000 12301751651 024431 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/test/java/org/apache/http/0040755 0000000 0000000 00000000000 12301751651 025410 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/test/java/org/apache/http/osgi/0040755 0000000 0000000 00000000000 12301751651 026351 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/test/java/org/apache/http/osgi/impl/0040755 0000000 0000000 00000000000 12301751651 027312 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000155 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-osgi/src/test/java/org/apache/http/osgi/impl/TestPropertiesUtils.javahttpcomponents-client-4.3.3/httpclient-osgi/src/test/java/org/apache/http/osgi/impl/TestPropertiesUt0100644 0000000 0000000 00000012772 12301751651 032550 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.osgi.impl; import static org.apache.http.osgi.impl.PropertiesUtils.to; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import org.junit.Test; /** * @since 4.3 */ public final class TestPropertiesUtils { @Test public void toBoolean() { assertConverted(true, null, boolean.class, true); assertConverted(true, null, Boolean.class, true); assertConverted(false, "false", boolean.class, null); assertConverted(false, "false", Boolean.class, null); // whatever value is interpreted as `false` by Boolean.valueOf assertConverted(false, "not a boolean", boolean.class, true); assertConverted(false, "not a boolean", Boolean.class, true); } @Test public void toSingleString() { assertConverted("fallback to default value", null, String.class, "fallback to default value"); // use an object which represents the string assertConverted("use the passed value", new StringBuilder("use the passed value"), String.class, null); // use the "identity" converter assertConverted("use the passed value", "use the passed value", String.class, null); // convert another object assertConverted("456789", 456789, String.class, null); } @Test public void toStringArray() { assertConvertedArray(new String[]{"fallback to default value"}, null, String[].class, new String[]{"fallback to default value"}); // a string is converted to an array with 1 element assertConvertedArray(new String[]{"a single string"}, "a single string", String[].class, null); // use an object which represents the string assertConvertedArray(new String[]{"null objects", "will be ignored"}, new Object[]{new StringBuilder("null objects"), null, new StringBuilder("will be ignored")}, String[].class, null); // use the "identity" converter assertConvertedArray(new String[]{"null objects", "will be ignored"}, new Object[]{"null objects", null, "will be ignored"}, String[].class, null); assertConvertedArray(new String[]{"fallback to default value"}, 456789, String[].class, new String[]{"fallback to default value"}); } @Test public void toInt() { assertConverted(123, null, int.class, 123); assertConverted(123, null, Integer.class, 123); assertConverted(456, "456", int.class, null); assertConverted(456, "456", Integer.class, null); assertConverted(789, "not an integer", int.class, 789); assertConverted(789, "not an integer", Integer.class, 789); } @Test public void toLong() { assertConverted(123l, null, long.class, 123l); assertConverted(123l, null, Long.class, 123l); assertConverted(456l, "456", long.class, null); assertConverted(456l, "456", Long.class, null); assertConverted(789l, "not a long", long.class, 789l); assertConverted(789l, "not a long", Long.class, 789l); } @Test public void toDouble() { assertConverted(123d, null, double.class, 123d); assertConverted(123d, null, Double.class, 123d); assertConverted(456d, "456", double.class, null); assertConverted(456d, "456", Double.class, null); assertConverted(789d, "not a double", double.class, 789d); assertConverted(789d, "not a double", Double.class, 789d); } private static void assertConverted( final T expected, final Object propValue, final Class targetType, final T defaultValue) { final T actual = to(propValue, targetType, defaultValue); assertEquals(expected, actual); } private static void assertConvertedArray( final T[] expected, final Object propValue, final Class targetType, final T[] defaultValue) { final T[] actual = to(propValue, targetType, defaultValue); assertArrayEquals(expected, actual); } } httpcomponents-client-4.3.3/httpclient-win/0040755 0000000 0000000 00000000000 12301751651 017566 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-win/pom.xml0100644 0000000 0000000 00000007732 12301751651 021111 0ustar000000000 0000000 4.0.0 org.apache.httpcomponents httpcomponents-client 4.3-beta3-SNAPSHOT winauth-jni Windows Integrated Auth Windows Integrated Authentication for Apache HttpClient via JNI http://hc.apache.org/httpcomponents-client jar org.apache.httpcomponents httpclient ${project.version} compile net.java.dev.jna jna compile net.java.dev.jna jna-platform compile junit junit test maven-javadoc-plugin ${hc.javadoc.version} true ${maven.compiler.source} http://download.oracle.com/javase/1.5.0/docs/api/ http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/ javadoc maven-project-info-reports-plugin ${hc.project-info.version} false dependencies dependency-info summary maven-jxr-plugin ${hc.jxr.version} maven-surefire-report-plugin ${hc.surefire-report.version} httpcomponents-client-4.3.3/httpclient-win/src/0040755 0000000 0000000 00000000000 12301751651 020355 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-win/src/main/0040755 0000000 0000000 00000000000 12301751651 021301 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-win/src/main/java/0040755 0000000 0000000 00000000000 12301751651 022222 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-win/src/main/java/org/0040755 0000000 0000000 00000000000 12301751651 023011 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/0040755 0000000 0000000 00000000000 12301751651 024232 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/http/0040755 0000000 0000000 00000000000 12301751651 025211 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/http/impl/0040755 0000000 0000000 00000000000 12301751651 026152 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/http/impl/auth/0040755 0000000 0000000 00000000000 12301751651 027113 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/http/impl/auth/win/0040755 0000000 0000000 00000000000 12301751651 027710 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000166 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/http/impl/auth/win/CurrentWindowsCredentials.javahttpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/http/impl/auth/win/CurrentWindow0100644 0000000 0000000 00000005606 12301751651 032451 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth.win; import java.io.Serializable; import java.security.Principal; import org.apache.http.annotation.Immutable; import org.apache.http.auth.Credentials; import com.sun.jna.platform.win32.Secur32Util; import com.sun.jna.platform.win32.Secur32.EXTENDED_NAME_FORMAT; /** * Returns the current Windows user credentials *

* EXPERIMENTAL * * @since 4.3 */ @Immutable public class CurrentWindowsCredentials implements Credentials, Serializable, Principal { private static final long serialVersionUID = 4361166468529298169L; /** * Get the SAM-compatible username of the currently logged-on user. * * @return String. */ public static String getCurrentUsername() { return Secur32Util.getUserNameEx(EXTENDED_NAME_FORMAT.NameSamCompatible); } private CurrentWindowsCredentials() { } private static class LazyHolder { private static final CurrentWindowsCredentials INSTANCE = new CurrentWindowsCredentials(); } public static CurrentWindowsCredentials get() { return LazyHolder.INSTANCE; } public Principal getUserPrincipal() { return this; } @Override public int hashCode() { return 245678; // always the same? } @Override public boolean equals(final Object o) { if (this == o) return true; if (o instanceof CurrentWindowsCredentials) { return true; } return false; } @Override public String toString() { return getCurrentUsername(); } /** * Returns an empty password */ public String getPassword() { return ""; } public String getName() { return getCurrentUsername(); } } ././@LongLink0100644 0000000 0000000 00000000151 12302131606 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/http/impl/auth/win/package-info.javahttpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/http/impl/auth/win/package-info.0100644 0000000 0000000 00000002633 12301751651 032236 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * Auth scheme that makes use of JNA to implement Negotiate & NTLM on Windows Platforms. *

* Please note this class is considered experimental and may be discontinued or removed * in the future. */ package org.apache.http.impl.auth.win; ././@LongLink0100644 0000000 0000000 00000000163 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/http/impl/auth/win/WindowsNegotiateScheme.javahttpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/http/impl/auth/win/WindowsNegoti0100644 0000000 0000000 00000021665 12301751651 032442 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth.win; import java.util.Locale; import org.apache.commons.codec.binary.Base64; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AUTH; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.Credentials; import org.apache.http.auth.InvalidCredentialsException; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.client.config.AuthSchemes; import org.apache.http.impl.auth.AuthSchemeBase; import org.apache.http.message.BufferedHeader; import org.apache.http.protocol.HttpContext; import org.apache.http.util.CharArrayBuffer; import com.sun.jna.platform.win32.Secur32; import com.sun.jna.platform.win32.Sspi; import com.sun.jna.platform.win32.Sspi.CredHandle; import com.sun.jna.platform.win32.Sspi.CtxtHandle; import com.sun.jna.platform.win32.Sspi.SecBufferDesc; import com.sun.jna.platform.win32.Sspi.TimeStamp; import com.sun.jna.platform.win32.Win32Exception; import com.sun.jna.platform.win32.WinError; import com.sun.jna.ptr.IntByReference; /** * Auth scheme that makes use of JNA to implement Negotiate & NTLM on Windows Platforms. *

* This will delegate negotiation to the windows machine. *

* EXPERIMENTAL * * @since 4.3 */ @NotThreadSafe public class WindowsNegotiateScheme extends AuthSchemeBase { public static boolean isAvaliable() { String os = System.getProperty("os.name"); os = os != null ? os.toLowerCase(Locale.US) : null; if (os != null && os.contains("windows")) { try { return Sspi.MAX_TOKEN_SIZE > 0; } catch (Exception ignore) { // Likely ClassNotFound return false; } } return false; } // NTLM or Negotiate private final String scheme; private CredHandle clientCred; private CtxtHandle sppicontext; private boolean continueNeeded; private String challenge; public WindowsNegotiateScheme(final String scheme) { super(); this.scheme = (scheme == null) ? AuthSchemes.SPNEGO : scheme; this.challenge = null; this.continueNeeded = true; } public void dispose() { if (clientCred != null && !clientCred.isNull()) { final int rc = Secur32.INSTANCE.FreeCredentialsHandle(clientCred); if (WinError.SEC_E_OK != rc) { throw new Win32Exception(rc); } } if (sppicontext != null && !sppicontext.isNull()) { final int rc = Secur32.INSTANCE.DeleteSecurityContext(sppicontext); if (WinError.SEC_E_OK != rc) { throw new Win32Exception(rc); } } continueNeeded = true; // waiting clientCred = null; sppicontext = null; } @Override public void finalize() throws Throwable { dispose(); super.finalize(); } public String getSchemeName() { return scheme; } // String parameters not supported public String getParameter(final String name) { return null; } // NTLM/Negotiate do not support authentication realms public String getRealm() { return null; } public boolean isConnectionBased() { return true; } @Override protected void parseChallenge( final CharArrayBuffer buffer, final int beginIndex, final int endIndex) throws MalformedChallengeException { this.challenge = buffer.substringTrimmed(beginIndex, endIndex); if (this.challenge.length() == 0) { if (clientCred != null) { if (continueNeeded) { throw new RuntimeException("Unexpected token"); } dispose(); } } } @Override public Header authenticate( final Credentials credentials, final HttpRequest request, final HttpContext context) throws AuthenticationException { final String response; if (clientCred == null) { // ?? We don't use the credentials, should we allow anything? if (!(credentials instanceof CurrentWindowsCredentials)) { throw new InvalidCredentialsException( "Credentials cannot be used for " + getSchemeName() + " authentication: " + credentials.getClass().getName()); } // client credentials handle try { final String username = CurrentWindowsCredentials.getCurrentUsername(); final TimeStamp lifetime = new TimeStamp(); clientCred = new CredHandle(); final int rc = Secur32.INSTANCE.AcquireCredentialsHandle(username, scheme, Sspi.SECPKG_CRED_OUTBOUND, null, null, null, null, clientCred, lifetime); if (WinError.SEC_E_OK != rc) { throw new Win32Exception(rc); } response = getToken(null, null, username); } catch (Throwable t) { dispose(); throw new AuthenticationException("Authentication Failed", t); } } else if (this.challenge == null || this.challenge.length() == 0) { dispose(); throw new AuthenticationException("Authentication Failed"); } else { try { final byte[] continueTokenBytes = Base64.decodeBase64(this.challenge); final SecBufferDesc continueTokenBuffer = new SecBufferDesc( Sspi.SECBUFFER_TOKEN, continueTokenBytes); response = getToken(this.sppicontext, continueTokenBuffer, "localhost"); } catch (Throwable t) { dispose(); throw new AuthenticationException("Authentication Failed", t); } } final CharArrayBuffer buffer = new CharArrayBuffer(scheme.length() + 30); if (isProxy()) { buffer.append(AUTH.PROXY_AUTH_RESP); } else { buffer.append(AUTH.WWW_AUTH_RESP); } buffer.append(": "); buffer.append(scheme); // NTLM or Negotiate buffer.append(" "); buffer.append(response); return new BufferedHeader(buffer); } /** * @see http://msdn.microsoft.com/en-us/library/windows/desktop/aa375506(v=vs.85).aspx */ private String getToken( final CtxtHandle continueCtx, final SecBufferDesc continueToken, final String targetName) { final IntByReference attr = new IntByReference(); final SecBufferDesc token = new SecBufferDesc( Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); sppicontext = new CtxtHandle(); final int rc = Secur32.INSTANCE.InitializeSecurityContext(clientCred, continueCtx, targetName, Sspi.ISC_REQ_CONNECTION, 0, Sspi.SECURITY_NATIVE_DREP, continueToken, 0, sppicontext, token, attr, null); switch (rc) { case WinError.SEC_I_CONTINUE_NEEDED: continueNeeded = true; break; case WinError.SEC_E_OK: dispose(); // Don't keep the context continueNeeded = false; break; default: dispose(); throw new Win32Exception(rc); } return Base64.encodeBase64String(token.getBytes()); } public boolean isComplete() { return !continueNeeded; } @Deprecated public Header authenticate( final Credentials credentials, final HttpRequest request) throws AuthenticationException { return authenticate(credentials, request, null); } } ././@LongLink0100644 0000000 0000000 00000000172 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/http/impl/auth/win/WindowsNegotiateSchemeFactory.javahttpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/http/impl/auth/win/WindowsNegoti0100644 0000000 0000000 00000003512 12301751651 032431 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth.win; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.client.config.AuthSchemes; import org.apache.http.protocol.HttpContext; /** * {@link AuthSchemeProvider} implementation that creates and initializes * {@link WindowsNegotiateScheme} using JNA to Negotiate credentials *

* EXPERIMENTAL * * @since 4.3 */ @Immutable public class WindowsNegotiateSchemeFactory implements AuthSchemeProvider { public AuthScheme create(final HttpContext context) { return new WindowsNegotiateScheme(AuthSchemes.SPNEGO); } } ././@LongLink0100644 0000000 0000000 00000000165 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/http/impl/auth/win/WindowsNTLMSchemeFactory.javahttpcomponents-client-4.3.3/httpclient-win/src/main/java/org/apache/http/impl/auth/win/WindowsNTLMSc0100644 0000000 0000000 00000003474 12301751651 032253 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.impl.auth.win; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.client.config.AuthSchemes; import org.apache.http.protocol.HttpContext; /** * {@link AuthSchemeProvider} implementation that creates and initializes * {@link WindowsNegotiateScheme} using JNA to implement NTLM *

* EXPERIMENTAL * * @since 4.3 */ @Immutable public class WindowsNTLMSchemeFactory implements AuthSchemeProvider { public AuthScheme create(final HttpContext context) { return new WindowsNegotiateScheme(AuthSchemes.NTLM); } } httpcomponents-client-4.3.3/httpmime/0040755 0000000 0000000 00000000000 12301752721 016443 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/pom.xml0100644 0000000 0000000 00000011262 12301751744 017763 0ustar000000000 0000000 4.0.0 org.apache.httpcomponents httpcomponents-client 4.3.3 httpmime Apache HttpClient Mime HttpComponents HttpClient - MIME coded entities http://hc.apache.org/httpcomponents-client jar org.apache.httpcomponents httpclient ${project.version} compile junit junit test src/main/resources true **/*.properties org.codehaus.mojo build-helper-maven-plugin 1.8 add-source generate-sources add-source src/main/java-deprecated maven-javadoc-plugin ${hc.javadoc.version} true ${maven.compiler.source} http://download.oracle.com/javase/1.5.0/docs/api/ http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/ javadoc maven-project-info-reports-plugin ${hc.project-info.version} false dependencies dependency-info summary maven-jxr-plugin ${hc.jxr.version} maven-surefire-report-plugin ${hc.surefire-report.version} httpcomponents-client-4.3.3/httpmime/src/0040755 0000000 0000000 00000000000 12301751742 017234 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/examples/0040755 0000000 0000000 00000000000 12301751742 021052 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/examples/org/0040755 0000000 0000000 00000000000 12301751742 021641 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/examples/org/apache/0040755 0000000 0000000 00000000000 12301751742 023062 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/examples/org/apache/http/0040755 0000000 0000000 00000000000 12301751742 024041 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/examples/org/apache/http/examples/0040755 0000000 0000000 00000000000 12301751742 025657 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/examples/org/apache/http/examples/entity/0040755 0000000 0000000 00000000000 12301751742 027173 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/examples/org/apache/http/examples/entity/mime/0040755 0000000 0000000 00000000000 12301751742 030122 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000164 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/examples/org/apache/http/examples/entity/mime/ClientMultipartFormPost.javahttpcomponents-client-4.3.3/httpmime/src/examples/org/apache/http/examples/entity/mime/ClientMultipa0100644 0000000 0000000 00000006507 12301751742 032624 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.examples.entity.mime; import java.io.File; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; /** * Example how to use multipart/form encoded POST request. */ public class ClientMultipartFormPost { public static void main(String[] args) throws Exception { if (args.length != 1) { System.out.println("File path not given"); System.exit(1); } CloseableHttpClient httpclient = HttpClients.createDefault(); try { HttpPost httppost = new HttpPost("http://localhost:8080" + "/servlets-examples/servlet/RequestInfoExample"); FileBody bin = new FileBody(new File(args[0])); StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN); HttpEntity reqEntity = MultipartEntityBuilder.create() .addPart("bin", bin) .addPart("comment", comment) .build(); httppost.setEntity(reqEntity); System.out.println("executing request " + httppost.getRequestLine()); CloseableHttpResponse response = httpclient.execute(httppost); try { System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); HttpEntity resEntity = response.getEntity(); if (resEntity != null) { System.out.println("Response content length: " + resEntity.getContentLength()); } EntityUtils.consume(resEntity); } finally { response.close(); } } finally { httpclient.close(); } } } httpcomponents-client-4.3.3/httpmime/src/main/0040755 0000000 0000000 00000000000 12301751744 020162 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/0040755 0000000 0000000 00000000000 12301751742 021101 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/0040755 0000000 0000000 00000000000 12301751742 021670 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/0040755 0000000 0000000 00000000000 12301751742 023111 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/0040755 0000000 0000000 00000000000 12301751742 024070 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/0040755 0000000 0000000 00000000000 12301751742 025404 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/0040755 0000000 0000000 00000000000 12301751743 026334 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000152 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/AbstractMultipartForm.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/AbstractMultipartForm0100644 0000000 0000000 00000016566 12301751743 032563 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.util.List; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.util.Args; import org.apache.http.util.ByteArrayBuffer; /** * HttpMultipart represents a collection of MIME multipart encoded content bodies. This class is * capable of operating either in the strict (RFC 822, RFC 2045, RFC 2046 compliant) or * the browser compatible modes. * * @since 4.3 */ abstract class AbstractMultipartForm { private static ByteArrayBuffer encode( final Charset charset, final String string) { final ByteBuffer encoded = charset.encode(CharBuffer.wrap(string)); final ByteArrayBuffer bab = new ByteArrayBuffer(encoded.remaining()); bab.append(encoded.array(), encoded.position(), encoded.remaining()); return bab; } private static void writeBytes( final ByteArrayBuffer b, final OutputStream out) throws IOException { out.write(b.buffer(), 0, b.length()); } private static void writeBytes( final String s, final Charset charset, final OutputStream out) throws IOException { final ByteArrayBuffer b = encode(charset, s); writeBytes(b, out); } private static void writeBytes( final String s, final OutputStream out) throws IOException { final ByteArrayBuffer b = encode(MIME.DEFAULT_CHARSET, s); writeBytes(b, out); } protected static void writeField( final MinimalField field, final OutputStream out) throws IOException { writeBytes(field.getName(), out); writeBytes(FIELD_SEP, out); writeBytes(field.getBody(), out); writeBytes(CR_LF, out); } protected static void writeField( final MinimalField field, final Charset charset, final OutputStream out) throws IOException { writeBytes(field.getName(), charset, out); writeBytes(FIELD_SEP, out); writeBytes(field.getBody(), charset, out); writeBytes(CR_LF, out); } private static final ByteArrayBuffer FIELD_SEP = encode(MIME.DEFAULT_CHARSET, ": "); private static final ByteArrayBuffer CR_LF = encode(MIME.DEFAULT_CHARSET, "\r\n"); private static final ByteArrayBuffer TWO_DASHES = encode(MIME.DEFAULT_CHARSET, "--"); private final String subType; protected final Charset charset; private final String boundary; /** * Creates an instance with the specified settings. * * @param subType MIME subtype - must not be {@code null} * @param charset the character set to use. May be {@code null}, in which case {@link MIME#DEFAULT_CHARSET} - i.e. US-ASCII - is used. * @param boundary to use - must not be {@code null} * @throws IllegalArgumentException if charset is null or boundary is null */ public AbstractMultipartForm(final String subType, final Charset charset, final String boundary) { super(); Args.notNull(subType, "Multipart subtype"); Args.notNull(boundary, "Multipart boundary"); this.subType = subType; this.charset = charset != null ? charset : MIME.DEFAULT_CHARSET; this.boundary = boundary; } public AbstractMultipartForm(final String subType, final String boundary) { this(subType, null, boundary); } public String getSubType() { return this.subType; } public Charset getCharset() { return this.charset; } public abstract List getBodyParts(); public String getBoundary() { return this.boundary; } void doWriteTo( final OutputStream out, final boolean writeContent) throws IOException { final ByteArrayBuffer boundary = encode(this.charset, getBoundary()); for (final FormBodyPart part: getBodyParts()) { writeBytes(TWO_DASHES, out); writeBytes(boundary, out); writeBytes(CR_LF, out); formatMultipartHeader(part, out); writeBytes(CR_LF, out); if (writeContent) { part.getBody().writeTo(out); } writeBytes(CR_LF, out); } writeBytes(TWO_DASHES, out); writeBytes(boundary, out); writeBytes(TWO_DASHES, out); writeBytes(CR_LF, out); } /** * Write the multipart header fields; depends on the style. */ protected abstract void formatMultipartHeader( final FormBodyPart part, final OutputStream out) throws IOException; /** * Writes out the content in the multipart/form encoding. This method * produces slightly different formatting depending on its compatibility * mode. */ public void writeTo(final OutputStream out) throws IOException { doWriteTo(out, true); } /** * Determines the total length of the multipart content (content length of * individual parts plus that of extra elements required to delimit the parts * from one another). If any of the @{link BodyPart}s contained in this object * is of a streaming entity of unknown length the total length is also unknown. *

* This method buffers only a small amount of data in order to determine the * total length of the entire entity. The content of individual parts is not * buffered. * * @return total length of the multipart entity if known, -1 * otherwise. */ public long getTotalLength() { long contentLen = 0; for (final FormBodyPart part: getBodyParts()) { final ContentBody body = part.getBody(); final long len = body.getContentLength(); if (len >= 0) { contentLen += len; } else { return -1; } } final ByteArrayOutputStream out = new ByteArrayOutputStream(); try { doWriteTo(out, false); final byte[] extra = out.toByteArray(); return contentLen + extra.length; } catch (final IOException ex) { // Should never happen return -1; } } } httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/FormBodyPart.java0100644 0000000 0000000 00000007646 12301751743 031561 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.content.AbstractContentBody; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.util.Args; /** * FormBodyPart class represents a content body that can be used as a part of multipart encoded * entities. This class automatically populates the header with standard fields based on * the content description of the enclosed body. * * @since 4.0 */ public class FormBodyPart { private final String name; private final Header header; private final ContentBody body; public FormBodyPart(final String name, final ContentBody body) { super(); Args.notNull(name, "Name"); Args.notNull(body, "Body"); this.name = name; this.body = body; this.header = new Header(); generateContentDisp(body); generateContentType(body); generateTransferEncoding(body); } public String getName() { return this.name; } public ContentBody getBody() { return this.body; } public Header getHeader() { return this.header; } public void addField(final String name, final String value) { Args.notNull(name, "Field name"); this.header.addField(new MinimalField(name, value)); } protected void generateContentDisp(final ContentBody body) { final StringBuilder buffer = new StringBuilder(); buffer.append("form-data; name=\""); buffer.append(getName()); buffer.append("\""); if (body.getFilename() != null) { buffer.append("; filename=\""); buffer.append(body.getFilename()); buffer.append("\""); } addField(MIME.CONTENT_DISPOSITION, buffer.toString()); } protected void generateContentType(final ContentBody body) { final ContentType contentType; if (body instanceof AbstractContentBody) { contentType = ((AbstractContentBody) body).getContentType(); } else { contentType = null; } if (contentType != null) { addField(MIME.CONTENT_TYPE, contentType.toString()); } else { final StringBuilder buffer = new StringBuilder(); buffer.append(body.getMimeType()); // MimeType cannot be null if (body.getCharset() != null) { // charset may legitimately be null buffer.append("; charset="); buffer.append(body.getCharset()); } addField(MIME.CONTENT_TYPE, buffer.toString()); } } protected void generateTransferEncoding(final ContentBody body) { addField(MIME.CONTENT_TRANSFER_ENC, body.getTransferEncoding()); // TE cannot be null } } httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/Header.java0100644 0000000 0000000 00000011010 12301751743 030355 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; /** * The header of an entity (see RFC 2045). */ public class Header implements Iterable { private final List fields; private final Map> fieldMap; public Header() { super(); this.fields = new LinkedList(); this.fieldMap = new HashMap>(); } public void addField(final MinimalField field) { if (field == null) { return; } final String key = field.getName().toLowerCase(Locale.US); List values = this.fieldMap.get(key); if (values == null) { values = new LinkedList(); this.fieldMap.put(key, values); } values.add(field); this.fields.add(field); } public List getFields() { return new ArrayList(this.fields); } public MinimalField getField(final String name) { if (name == null) { return null; } final String key = name.toLowerCase(Locale.US); final List list = this.fieldMap.get(key); if (list != null && !list.isEmpty()) { return list.get(0); } return null; } public List getFields(final String name) { if (name == null) { return null; } final String key = name.toLowerCase(Locale.US); final List list = this.fieldMap.get(key); if (list == null || list.isEmpty()) { return Collections.emptyList(); } else { return new ArrayList(list); } } public int removeFields(final String name) { if (name == null) { return 0; } final String key = name.toLowerCase(Locale.US); final List removed = fieldMap.remove(key); if (removed == null || removed.isEmpty()) { return 0; } this.fields.removeAll(removed); return removed.size(); } public void setField(final MinimalField field) { if (field == null) { return; } final String key = field.getName().toLowerCase(Locale.US); final List list = fieldMap.get(key); if (list == null || list.isEmpty()) { addField(field); return; } list.clear(); list.add(field); int firstOccurrence = -1; int index = 0; for (final Iterator it = this.fields.iterator(); it.hasNext(); index++) { final MinimalField f = it.next(); if (f.getName().equalsIgnoreCase(field.getName())) { it.remove(); if (firstOccurrence == -1) { firstOccurrence = index; } } } this.fields.add(firstOccurrence, field); } public Iterator iterator() { return Collections.unmodifiableList(fields).iterator(); } @Override public String toString() { return this.fields.toString(); } } ././@LongLink0100644 0000000 0000000 00000000163 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/HttpBrowserCompatibleMultipart.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/HttpBrowserCompatible0100644 0000000 0000000 00000005266 12301751743 032550 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.List; /** * HttpBrowserCompatibleMultipart represents a collection of MIME multipart encoded * content bodies. This class is emulates browser compatibility, e.g. IE 5 or earlier. * * @since 4.3 */ class HttpBrowserCompatibleMultipart extends AbstractMultipartForm { private final List parts; public HttpBrowserCompatibleMultipart( final String subType, final Charset charset, final String boundary, final List parts) { super(subType, charset, boundary); this.parts = parts; } @Override public List getBodyParts() { return this.parts; } /** * Write the multipart header fields; depends on the style. */ @Override protected void formatMultipartHeader( final FormBodyPart part, final OutputStream out) throws IOException { // For browser-compatible, only write Content-Disposition // Use content charset final Header header = part.getHeader(); final MinimalField cd = header.getField(MIME.CONTENT_DISPOSITION); writeField(cd, this.charset, out); final String filename = part.getBody().getFilename(); if (filename != null) { final MinimalField ct = header.getField(MIME.CONTENT_TYPE); writeField(ct, this.charset, out); } } } ././@LongLink0100644 0000000 0000000 00000000146 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/HttpMultipartMode.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/HttpMultipartMode.jav0100644 0000000 0000000 00000002740 12301751743 032464 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; /** * * @since 4.0 */ public enum HttpMultipartMode { /** RFC 822, RFC 2045, RFC 2046 compliant */ STRICT, /** browser-compatible mode, i.e. only write Content-Disposition; use content charset */ BROWSER_COMPATIBLE, /** RFC 6532 compliant */ RFC6532 } ././@LongLink0100644 0000000 0000000 00000000151 12302131606 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/HttpRFC6532Multipart.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/HttpRFC6532Multipart.0100644 0000000 0000000 00000004625 12301751743 032035 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.List; /** * HttpRFC6532Multipart represents a collection of MIME multipart encoded content bodies, * implementing the strict (RFC 822, RFC 2045, RFC 2046 compliant) interpretation * of the spec, with the exception of allowing UTF-8 headers, as per RFC6532. * * @since 4.3 */ class HttpRFC6532Multipart extends AbstractMultipartForm { private final List parts; public HttpRFC6532Multipart( final String subType, final Charset charset, final String boundary, final List parts) { super(subType, charset, boundary); this.parts = parts; } @Override public List getBodyParts() { return this.parts; } @Override protected void formatMultipartHeader( final FormBodyPart part, final OutputStream out) throws IOException { // For RFC6532, we output all fields with UTF-8 encoding. final Header header = part.getHeader(); for (final MinimalField field: header) { writeField(field, MIME.UTF8_CHARSET, out); } } } ././@LongLink0100644 0000000 0000000 00000000150 12302131606 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/HttpStrictMultipart.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/HttpStrictMultipart.j0100644 0000000 0000000 00000004510 12301751743 032516 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.List; /** * HttpStrictMultipart represents a collection of MIME multipart encoded content bodies, * implementing the strict (RFC 822, RFC 2045, RFC 2046 compliant) interpretation * of the spec. * * @since 4.3 */ class HttpStrictMultipart extends AbstractMultipartForm { private final List parts; public HttpStrictMultipart( final String subType, final Charset charset, final String boundary, final List parts) { super(subType, charset, boundary); this.parts = parts; } @Override public List getBodyParts() { return this.parts; } @Override protected void formatMultipartHeader( final FormBodyPart part, final OutputStream out) throws IOException { // For strict, we output all fields with MIME-standard encoding. final Header header = part.getHeader(); for (final MinimalField field: header) { writeField(field, out); } } } httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/MIME.java0100644 0000000 0000000 00000003634 12301751743 027731 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import org.apache.http.Consts; import java.nio.charset.Charset; /** * * @since 4.0 */ public final class MIME { public static final String CONTENT_TYPE = "Content-Type"; public static final String CONTENT_TRANSFER_ENC = "Content-Transfer-Encoding"; public static final String CONTENT_DISPOSITION = "Content-Disposition"; public static final String ENC_8BIT = "8bit"; public static final String ENC_BINARY = "binary"; /** The default character set to be used, i.e. "US-ASCII" */ public static final Charset DEFAULT_CHARSET = Consts.ASCII; /** UTF-8 is used for RFC6532 */ public static final Charset UTF8_CHARSET = Consts.UTF_8; } httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/MinimalField.java0100644 0000000 0000000 00000003526 12301751743 031534 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; /** * Minimal MIME field. * * @since 4.0 */ public class MinimalField { private final String name; private final String value; public MinimalField(final String name, final String value) { super(); this.name = name; this.value = value; } public String getName() { return this.name; } public String getBody() { return this.value; } @Override public String toString() { final StringBuilder buffer = new StringBuilder(); buffer.append(this.name); buffer.append(": "); buffer.append(this.value); return buffer.toString(); } } ././@LongLink0100644 0000000 0000000 00000000153 12302131606 011624 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/MultipartEntityBuilder.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/MultipartEntityBuilde0100644 0000000 0000000 00000016324 12301751743 032565 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import java.io.File; import java.io.InputStream; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Random; import org.apache.http.HttpEntity; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.content.ByteArrayBody; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.InputStreamBody; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.util.Args; /** * Builder for multipart {@link HttpEntity}s. * * @since 4.3 */ public class MultipartEntityBuilder { /** * The pool of ASCII chars to be used for generating a multipart boundary. */ private final static char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" .toCharArray(); private final static String DEFAULT_SUBTYPE = "form-data"; private String subType = DEFAULT_SUBTYPE; private HttpMultipartMode mode = HttpMultipartMode.STRICT; private String boundary = null; private Charset charset = null; private List bodyParts = null; public static MultipartEntityBuilder create() { return new MultipartEntityBuilder(); } MultipartEntityBuilder() { super(); } public MultipartEntityBuilder setMode(final HttpMultipartMode mode) { this.mode = mode; return this; } public MultipartEntityBuilder setLaxMode() { this.mode = HttpMultipartMode.BROWSER_COMPATIBLE; return this; } public MultipartEntityBuilder setStrictMode() { this.mode = HttpMultipartMode.STRICT; return this; } public MultipartEntityBuilder setBoundary(final String boundary) { this.boundary = boundary; return this; } public MultipartEntityBuilder setCharset(final Charset charset) { this.charset = charset; return this; } MultipartEntityBuilder addPart(final FormBodyPart bodyPart) { if (bodyPart == null) { return this; } if (this.bodyParts == null) { this.bodyParts = new ArrayList(); } this.bodyParts.add(bodyPart); return this; } public MultipartEntityBuilder addPart(final String name, final ContentBody contentBody) { Args.notNull(name, "Name"); Args.notNull(contentBody, "Content body"); return addPart(new FormBodyPart(name, contentBody)); } public MultipartEntityBuilder addTextBody( final String name, final String text, final ContentType contentType) { return addPart(name, new StringBody(text, contentType)); } public MultipartEntityBuilder addTextBody( final String name, final String text) { return addTextBody(name, text, ContentType.DEFAULT_TEXT); } public MultipartEntityBuilder addBinaryBody( final String name, final byte[] b, final ContentType contentType, final String filename) { return addPart(name, new ByteArrayBody(b, contentType, filename)); } public MultipartEntityBuilder addBinaryBody( final String name, final byte[] b) { return addBinaryBody(name, b, ContentType.DEFAULT_BINARY, null); } public MultipartEntityBuilder addBinaryBody( final String name, final File file, final ContentType contentType, final String filename) { return addPart(name, new FileBody(file, contentType, filename)); } public MultipartEntityBuilder addBinaryBody( final String name, final File file) { return addBinaryBody(name, file, ContentType.DEFAULT_BINARY, file != null ? file.getName() : null); } public MultipartEntityBuilder addBinaryBody( final String name, final InputStream stream, final ContentType contentType, final String filename) { return addPart(name, new InputStreamBody(stream, contentType, filename)); } public MultipartEntityBuilder addBinaryBody(final String name, final InputStream stream) { return addBinaryBody(name, stream, ContentType.DEFAULT_BINARY, null); } private String generateContentType( final String boundary, final Charset charset) { final StringBuilder buffer = new StringBuilder(); buffer.append("multipart/form-data; boundary="); buffer.append(boundary); if (charset != null) { buffer.append("; charset="); buffer.append(charset.name()); } return buffer.toString(); } private String generateBoundary() { final StringBuilder buffer = new StringBuilder(); final Random rand = new Random(); final int count = rand.nextInt(11) + 30; // a random size from 30 to 40 for (int i = 0; i < count; i++) { buffer.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]); } return buffer.toString(); } MultipartFormEntity buildEntity() { final String st = subType != null ? subType : DEFAULT_SUBTYPE; final Charset cs = charset; final String b = boundary != null ? boundary : generateBoundary(); final List bps = bodyParts != null ? new ArrayList(bodyParts) : Collections.emptyList(); final HttpMultipartMode m = mode != null ? mode : HttpMultipartMode.STRICT; final AbstractMultipartForm form; switch (m) { case BROWSER_COMPATIBLE: form = new HttpBrowserCompatibleMultipart(st, cs, b, bps); break; case RFC6532: form = new HttpRFC6532Multipart(st, cs, b, bps); break; default: form = new HttpStrictMultipart(st, cs, b, bps); } return new MultipartFormEntity(form, generateContentType(b, cs), form.getTotalLength()); } public HttpEntity build() { return buildEntity(); } } ././@LongLink0100644 0000000 0000000 00000000150 12302131606 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/MultipartFormEntity.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/MultipartFormEntity.j0100644 0000000 0000000 00000006027 12301751743 032513 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.HTTP; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; class MultipartFormEntity implements HttpEntity { private final AbstractMultipartForm multipart; private final Header contentType; private final long contentLength; MultipartFormEntity( final AbstractMultipartForm multipart, final String contentType, final long contentLength) { super(); this.multipart = multipart; this.contentType = new BasicHeader(HTTP.CONTENT_TYPE, contentType); this.contentLength = contentLength; } AbstractMultipartForm getMultipart() { return this.multipart; } public boolean isRepeatable() { return this.contentLength != -1; } public boolean isChunked() { return !isRepeatable(); } public boolean isStreaming() { return !isRepeatable(); } public long getContentLength() { return this.contentLength; } public Header getContentType() { return this.contentType; } public Header getContentEncoding() { return null; } public void consumeContent() throws IOException, UnsupportedOperationException{ if (isStreaming()) { throw new UnsupportedOperationException( "Streaming entity does not implement #consumeContent()"); } } public InputStream getContent() throws IOException { throw new UnsupportedOperationException( "Multipart form entity does not implement #getContent()"); } public void writeTo(final OutputStream outstream) throws IOException { this.multipart.writeTo(outstream); } } httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/package-info.java0100644 0000000 0000000 00000002371 12301751743 031523 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * MIME coded HTTP entity implementations. */ package org.apache.http.entity.mime; httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/0040755 0000000 0000000 00000000000 12301751743 030006 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000160 12302131606 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/AbstractContentBody.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/AbstractConte0100644 0000000 0000000 00000005417 12301751743 032471 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime.content; import java.nio.charset.Charset; import org.apache.http.entity.ContentType; import org.apache.http.util.Args; /** * * @since 4.0 */ public abstract class AbstractContentBody implements ContentBody { private final ContentType contentType; /** * @since 4.3 */ public AbstractContentBody(final ContentType contentType) { super(); Args.notNull(contentType, "Content type"); this.contentType = contentType; } /** * @deprecated (4.3) use {@link AbstractContentBody#AbstractContentBody(ContentType)} */ @Deprecated public AbstractContentBody(final String mimeType) { this(ContentType.parse(mimeType)); } /** * @since 4.3 */ public ContentType getContentType() { return this.contentType; } public String getMimeType() { return this.contentType.getMimeType(); } public String getMediaType() { final String mimeType = this.contentType.getMimeType(); final int i = mimeType.indexOf('/'); if (i != -1) { return mimeType.substring(0, i); } else { return mimeType; } } public String getSubType() { final String mimeType = this.contentType.getMimeType(); final int i = mimeType.indexOf('/'); if (i != -1) { return mimeType.substring(i + 1); } else { return null; } } public String getCharset() { final Charset charset = this.contentType.getCharset(); return charset != null ? charset.name() : null; } } ././@LongLink0100644 0000000 0000000 00000000152 12302131606 011623 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/ByteArrayBody.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/ByteArrayBody0100644 0000000 0000000 00000006524 12301751743 032455 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime.content; import java.io.IOException; import java.io.OutputStream; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MIME; import org.apache.http.util.Args; /** * Binary body part backed by a byte array. * * @see org.apache.http.entity.mime.MultipartEntityBuilder * * @since 4.1 */ public class ByteArrayBody extends AbstractContentBody { /** * The contents of the file contained in this part. */ private final byte[] data; /** * The name of the file contained in this part. */ private final String filename; /** * Creates a new ByteArrayBody. * * @param data The contents of the file contained in this part. * @param mimeType The MIME type of the file contained in this part. * @param filename The name of the file contained in this part. * * @deprecated (4.3) use {@link ByteArrayBody#ByteArrayBody(byte[], ContentType, String)} * or {@link org.apache.http.entity.mime.MultipartEntityBuilder} */ @Deprecated public ByteArrayBody(final byte[] data, final String mimeType, final String filename) { this(data, ContentType.create(mimeType), filename); } /** * @since 4.3 */ public ByteArrayBody(final byte[] data, final ContentType contentType, final String filename) { super(contentType); Args.notNull(data, "byte[]"); this.data = data; this.filename = filename; } /** * Creates a new ByteArrayBody. * * @param data The contents of the file contained in this part. * @param filename The name of the file contained in this part. */ public ByteArrayBody(final byte[] data, final String filename) { this(data, "application/octet-stream", filename); } public String getFilename() { return filename; } public void writeTo(final OutputStream out) throws IOException { out.write(data); } @Override public String getCharset() { return null; } public String getTransferEncoding() { return MIME.ENC_BINARY; } public long getContentLength() { return data.length; } } ././@LongLink0100644 0000000 0000000 00000000150 12302131606 011621 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/ContentBody.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/ContentBody.j0100644 0000000 0000000 00000002661 12301751743 032413 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime.content; import java.io.IOException; import java.io.OutputStream; /** * * @since 4.0 */ public interface ContentBody extends ContentDescriptor { String getFilename(); void writeTo(OutputStream out) throws IOException; } ././@LongLink0100644 0000000 0000000 00000000156 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/ContentDescriptor.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/ContentDescri0100644 0000000 0000000 00000006255 12301751743 032502 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime.content; /** * Represents common content properties. */ public interface ContentDescriptor { /** * Returns the body descriptors MIME type. * @see #getMediaType() * @see #getSubType() * @return The MIME type, which has been parsed from the * content-type definition. Must not be null, but * "text/plain", if no content-type was specified. */ String getMimeType(); /** * Gets the defaulted MIME media type for this content. * For example TEXT, IMAGE, MULTIPART * @see #getMimeType() * @return the MIME media type when content-type specified, * otherwise the correct default (TEXT) */ String getMediaType(); /** * Gets the defaulted MIME sub type for this content. * @see #getMimeType() * @return the MIME media type when content-type is specified, * otherwise the correct default (PLAIN) */ String getSubType(); /** *

The body descriptors character set, defaulted appropriately for the MIME type.

*

* For TEXT types, this will be defaulted to us-ascii. * For other types, when the charset parameter is missing this property will be null. *

* @return Character set, which has been parsed from the * content-type definition. Not null for TEXT types, when unset will * be set to default us-ascii. For other types, when unset, * null will be returned. */ String getCharset(); /** * Returns the body descriptors transfer encoding. * @return The transfer encoding. Must not be null, but "7bit", * if no transfer-encoding was specified. */ String getTransferEncoding(); /** * Returns the body descriptors content-length. * @return Content length, if known, or -1, to indicate the absence of a * content-length header. */ long getContentLength(); } ././@LongLink0100644 0000000 0000000 00000000145 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/FileBody.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/FileBody.java0100644 0000000 0000000 00000010232 12301751743 032341 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime.content; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MIME; import org.apache.http.util.Args; /** * Binary body part backed by a file. * * @see org.apache.http.entity.mime.MultipartEntityBuilder * * @since 4.0 */ public class FileBody extends AbstractContentBody { private final File file; private final String filename; /** * @since 4.1 * * @deprecated (4.3) use {@link FileBody#FileBody(File, ContentType, String)} * or {@link org.apache.http.entity.mime.MultipartEntityBuilder} */ @Deprecated public FileBody(final File file, final String filename, final String mimeType, final String charset) { this(file, ContentType.create(mimeType, charset), filename); } /** * @since 4.1 * * @deprecated (4.3) use {@link FileBody#FileBody(File, ContentType)} * or {@link org.apache.http.entity.mime.MultipartEntityBuilder} */ @Deprecated public FileBody(final File file, final String mimeType, final String charset) { this(file, null, mimeType, charset); } /** * @deprecated (4.3) use {@link FileBody#FileBody(File, ContentType)} * or {@link org.apache.http.entity.mime.MultipartEntityBuilder} */ @Deprecated public FileBody(final File file, final String mimeType) { this(file, ContentType.create(mimeType), null); } public FileBody(final File file) { this(file, ContentType.DEFAULT_BINARY, file != null ? file.getName() : null); } /** * @since 4.3 */ public FileBody(final File file, final ContentType contentType, final String filename) { super(contentType); Args.notNull(file, "File"); this.file = file; this.filename = filename; } /** * @since 4.3 */ public FileBody(final File file, final ContentType contentType) { this(file, contentType, null); } public InputStream getInputStream() throws IOException { return new FileInputStream(this.file); } public void writeTo(final OutputStream out) throws IOException { Args.notNull(out, "Output stream"); final InputStream in = new FileInputStream(this.file); try { final byte[] tmp = new byte[4096]; int l; while ((l = in.read(tmp)) != -1) { out.write(tmp, 0, l); } out.flush(); } finally { in.close(); } } public String getTransferEncoding() { return MIME.ENC_BINARY; } public long getContentLength() { return this.file.length(); } public String getFilename() { return filename; } public File getFile() { return this.file; } } ././@LongLink0100644 0000000 0000000 00000000154 12302131606 011625 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/InputStreamBody.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/InputStreamBo0100644 0000000 0000000 00000006413 12301751743 032466 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime.content; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MIME; import org.apache.http.util.Args; /** * Binary body part backed by an input stream. * * @see org.apache.http.entity.mime.MultipartEntityBuilder * * @since 4.0 */ public class InputStreamBody extends AbstractContentBody { private final InputStream in; private final String filename; /** * @since 4.1 * * @deprecated (4.3) use {@link InputStreamBody#InputStreamBody(InputStream, ContentType, * String)} or {@link org.apache.http.entity.mime.MultipartEntityBuilder} */ @Deprecated public InputStreamBody(final InputStream in, final String mimeType, final String filename) { this(in, ContentType.create(mimeType), filename); } public InputStreamBody(final InputStream in, final String filename) { this(in, ContentType.DEFAULT_BINARY, filename); } /** * @since 4.3 */ public InputStreamBody(final InputStream in, final ContentType contentType, final String filename) { super(contentType); Args.notNull(in, "Input stream"); this.in = in; this.filename = filename; } /** * @since 4.3 */ public InputStreamBody(final InputStream in, final ContentType contentType) { this(in, contentType, null); } public InputStream getInputStream() { return this.in; } public void writeTo(final OutputStream out) throws IOException { Args.notNull(out, "Output stream"); try { final byte[] tmp = new byte[4096]; int l; while ((l = this.in.read(tmp)) != -1) { out.write(tmp, 0, l); } out.flush(); } finally { this.in.close(); } } public String getTransferEncoding() { return MIME.ENC_BINARY; } public long getContentLength() { return -1; } public String getFilename() { return this.filename; } } ././@LongLink0100644 0000000 0000000 00000000151 12302131606 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/package-info.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/package-info.0100644 0000000 0000000 00000002371 12301751743 032333 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ /** * MIME body part implementations. */ package org.apache.http.entity.mime.content; ././@LongLink0100644 0000000 0000000 00000000147 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/StringBody.javahttpcomponents-client-4.3.3/httpmime/src/main/java/org/apache/http/entity/mime/content/StringBody.ja0100644 0000000 0000000 00000015345 12301751743 032413 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime.content; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; import org.apache.http.Consts; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MIME; import org.apache.http.util.Args; /** * Text body part backed by a byte array. * * @see org.apache.http.entity.mime.MultipartEntityBuilder * * @since 4.0 */ public class StringBody extends AbstractContentBody { private final byte[] content; /** * @since 4.1 * * @deprecated (4.3) use {@link StringBody#StringBody(String, ContentType)} * or {@link org.apache.http.entity.mime.MultipartEntityBuilder} */ @Deprecated public static StringBody create( final String text, final String mimeType, final Charset charset) throws IllegalArgumentException { try { return new StringBody(text, mimeType, charset); } catch (final UnsupportedEncodingException ex) { throw new IllegalArgumentException("Charset " + charset + " is not supported", ex); } } /** * @since 4.1 * * @deprecated (4.3) use {@link StringBody#StringBody(String, ContentType)} * or {@link org.apache.http.entity.mime.MultipartEntityBuilder} */ @Deprecated public static StringBody create( final String text, final Charset charset) throws IllegalArgumentException { return create(text, null, charset); } /** * @since 4.1 * * @deprecated (4.3) use {@link StringBody#StringBody(String, ContentType)} * or {@link org.apache.http.entity.mime.MultipartEntityBuilder} */ @Deprecated public static StringBody create(final String text) throws IllegalArgumentException { return create(text, null, null); } /** * Create a StringBody from the specified text, MIME type and character set. * * @param text to be used for the body, not {@code null} * @param mimeType the MIME type, not {@code null} * @param charset the character set, may be {@code null}, in which case the US-ASCII charset is used * @throws UnsupportedEncodingException * @throws IllegalArgumentException if the {@code text} parameter is null * * @deprecated (4.3) use {@link StringBody#StringBody(String, ContentType)} * or {@link org.apache.http.entity.mime.MultipartEntityBuilder} */ @Deprecated public StringBody( final String text, final String mimeType, final Charset charset) throws UnsupportedEncodingException { this(text, ContentType.create(mimeType, charset)); } /** * Create a StringBody from the specified text and character set. * The MIME type is set to "text/plain". * * @param text to be used for the body, not {@code null} * @param charset the character set, may be {@code null}, in which case the US-ASCII charset is used * @throws UnsupportedEncodingException * @throws IllegalArgumentException if the {@code text} parameter is null * * @deprecated (4.3) use {@link StringBody#StringBody(String, ContentType)} * or {@link org.apache.http.entity.mime.MultipartEntityBuilder} */ @Deprecated public StringBody(final String text, final Charset charset) throws UnsupportedEncodingException { this(text, "text/plain", charset); } /** * Create a StringBody from the specified text. * The MIME type is set to "text/plain". * The {@linkplain Consts#ASCII ASCII} charset is used. * * @param text to be used for the body, not {@code null} * @throws UnsupportedEncodingException * @throws IllegalArgumentException if the {@code text} parameter is null * * @deprecated (4.3) use {@link StringBody#StringBody(String, ContentType)} * or {@link org.apache.http.entity.mime.MultipartEntityBuilder} */ @Deprecated public StringBody(final String text) throws UnsupportedEncodingException { this(text, "text/plain", Consts.ASCII); } /** * @since 4.3 */ public StringBody(final String text, final ContentType contentType) { super(contentType); final Charset charset = contentType.getCharset(); final String csname = charset != null ? charset.name() : Consts.ASCII.name(); try { this.content = text.getBytes(csname); } catch (final UnsupportedEncodingException ex) { // Should never happen throw new UnsupportedCharsetException(csname); } } public Reader getReader() { final Charset charset = getContentType().getCharset(); return new InputStreamReader( new ByteArrayInputStream(this.content), charset != null ? charset : Consts.ASCII); } public void writeTo(final OutputStream out) throws IOException { Args.notNull(out, "Output stream"); final InputStream in = new ByteArrayInputStream(this.content); final byte[] tmp = new byte[4096]; int l; while ((l = in.read(tmp)) != -1) { out.write(tmp, 0, l); } out.flush(); } public String getTransferEncoding() { return MIME.ENC_8BIT; } public long getContentLength() { return this.content.length; } public String getFilename() { return null; } } httpcomponents-client-4.3.3/httpmime/src/main/java-deprecated/0040755 0000000 0000000 00000000000 12301751744 023201 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java-deprecated/org/0040755 0000000 0000000 00000000000 12301751744 023770 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java-deprecated/org/apache/0040755 0000000 0000000 00000000000 12301751744 025211 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java-deprecated/org/apache/http/0040755 0000000 0000000 00000000000 12301751744 026170 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java-deprecated/org/apache/http/entity/0040755 0000000 0000000 00000000000 12301751744 027504 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java-deprecated/org/apache/http/entity/mime/0040755 0000000 0000000 00000000000 12301751744 030433 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000155 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java-deprecated/org/apache/http/entity/mime/HttpMultipart.javahttpcomponents-client-4.3.3/httpmime/src/main/java-deprecated/org/apache/http/entity/mime/HttpMultip0100644 0000000 0000000 00000010767 12301751744 032500 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; /** * HttpMultipart represents a collection of MIME multipart encoded content bodies. This class is * capable of operating either in the strict (RFC 822, RFC 2045, RFC 2046 compliant) or * the browser compatible modes. * * @since 4.0 * * @deprecated (4.3) Use {@link MultipartEntityBuilder}. */ @Deprecated public class HttpMultipart extends AbstractMultipartForm { private final HttpMultipartMode mode; private final List parts; /** * Creates an instance with the specified settings. * * @param subType MIME subtype - must not be {@code null} * @param charset the character set to use. May be {@code null}, * in which case {@link MIME#DEFAULT_CHARSET} - i.e. US-ASCII - is used. * @param boundary to use - must not be {@code null} * @param mode the mode to use * @throws IllegalArgumentException if charset is null or boundary is null */ public HttpMultipart( final String subType, final Charset charset, final String boundary, final HttpMultipartMode mode) { super(subType, charset, boundary); this.mode = mode; this.parts = new ArrayList(); } /** * Creates an instance with the specified settings. * Mode is set to {@link HttpMultipartMode#STRICT} * * @param subType MIME subtype - must not be {@code null} * @param charset the character set to use. May be {@code null}, * in which case {@link MIME#DEFAULT_CHARSET} - i.e. US-ASCII - is used. * @param boundary to use - must not be {@code null} * @throws IllegalArgumentException if charset is null or boundary is null */ public HttpMultipart(final String subType, final Charset charset, final String boundary) { this(subType, charset, boundary, HttpMultipartMode.STRICT); } public HttpMultipart(final String subType, final String boundary) { this(subType, null, boundary); } public HttpMultipartMode getMode() { return this.mode; } @Override protected void formatMultipartHeader( final FormBodyPart part, final OutputStream out) throws IOException { final Header header = part.getHeader(); switch (this.mode) { case BROWSER_COMPATIBLE: // For browser-compatible, only write Content-Disposition // Use content charset final MinimalField cd = header.getField(MIME.CONTENT_DISPOSITION); writeField(cd, this.charset, out); final String filename = part.getBody().getFilename(); if (filename != null) { final MinimalField ct = header.getField(MIME.CONTENT_TYPE); writeField(ct, this.charset, out); } break; default: for (final MinimalField field: header) { writeField(field, out); } } } @Override public List getBodyParts() { return this.parts; } public void addBodyPart(final FormBodyPart part) { if (part == null) { return; } this.parts.add(part); } } ././@LongLink0100644 0000000 0000000 00000000157 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/java-deprecated/org/apache/http/entity/mime/MultipartEntity.javahttpcomponents-client-4.3.3/httpmime/src/main/java-deprecated/org/apache/http/entity/mime/MultipartE0100644 0000000 0000000 00000013167 12301751744 032451 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.Random; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.entity.mime.content.ContentBody; /** * Multipart/form coded HTTP entity consisting of multiple body parts. * * @since 4.0 * * @deprecated 4.3 Use {@link MultipartEntityBuilder}. */ @Deprecated public class MultipartEntity implements HttpEntity { /** * The pool of ASCII chars to be used for generating a multipart boundary. */ private final static char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" .toCharArray(); private final MultipartEntityBuilder builder; private volatile MultipartFormEntity entity; /** * Creates an instance using the specified parameters * @param mode the mode to use, may be {@code null}, in which case {@link HttpMultipartMode#STRICT} is used * @param boundary the boundary string, may be {@code null}, in which case {@link #generateBoundary()} is invoked to create the string * @param charset the character set to use, may be {@code null}, in which case {@link MIME#DEFAULT_CHARSET} - i.e. US-ASCII - is used. */ public MultipartEntity( final HttpMultipartMode mode, final String boundary, final Charset charset) { super(); this.builder = new MultipartEntityBuilder() .setMode(mode) .setCharset(charset) .setBoundary(boundary); this.entity = null; } /** * Creates an instance using the specified {@link HttpMultipartMode} mode. * Boundary and charset are set to {@code null}. * @param mode the desired mode */ public MultipartEntity(final HttpMultipartMode mode) { this(mode, null, null); } /** * Creates an instance using mode {@link HttpMultipartMode#STRICT} */ public MultipartEntity() { this(HttpMultipartMode.STRICT, null, null); } protected String generateContentType( final String boundary, final Charset charset) { final StringBuilder buffer = new StringBuilder(); buffer.append("multipart/form-data; boundary="); buffer.append(boundary); if (charset != null) { buffer.append("; charset="); buffer.append(charset.name()); } return buffer.toString(); } protected String generateBoundary() { final StringBuilder buffer = new StringBuilder(); final Random rand = new Random(); final int count = rand.nextInt(11) + 30; // a random size from 30 to 40 for (int i = 0; i < count; i++) { buffer.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]); } return buffer.toString(); } private MultipartFormEntity getEntity() { if (this.entity == null) { this.entity = this.builder.buildEntity(); } return this.entity; } public void addPart(final FormBodyPart bodyPart) { this.builder.addPart(bodyPart); this.entity = null; } public void addPart(final String name, final ContentBody contentBody) { addPart(new FormBodyPart(name, contentBody)); } public boolean isRepeatable() { return getEntity().isRepeatable(); } public boolean isChunked() { return getEntity().isChunked(); } public boolean isStreaming() { return getEntity().isStreaming(); } public long getContentLength() { return getEntity().getContentLength(); } public Header getContentType() { return getEntity().getContentType(); } public Header getContentEncoding() { return getEntity().getContentEncoding(); } public void consumeContent() throws IOException, UnsupportedOperationException{ if (isStreaming()) { throw new UnsupportedOperationException( "Streaming entity does not implement #consumeContent()"); } } public InputStream getContent() throws IOException, UnsupportedOperationException { throw new UnsupportedOperationException( "Multipart form entity does not implement #getContent()"); } public void writeTo(final OutputStream outstream) throws IOException { getEntity().writeTo(outstream); } } httpcomponents-client-4.3.3/httpmime/src/main/resources/0040755 0000000 0000000 00000000000 12301751744 022174 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/resources/org/0040755 0000000 0000000 00000000000 12301751744 022763 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/resources/org/apache/0040755 0000000 0000000 00000000000 12301751744 024204 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/resources/org/apache/http/0040755 0000000 0000000 00000000000 12301751744 025163 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/resources/org/apache/http/entity/0040755 0000000 0000000 00000000000 12301751744 026477 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/resources/org/apache/http/entity/mime/0040755 0000000 0000000 00000000000 12301751744 027426 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000147 12302131606 011627 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/main/resources/org/apache/http/entity/mime/version.propertieshttpcomponents-client-4.3.3/httpmime/src/main/resources/org/apache/http/entity/mime/version.properti0100644 0000000 0000000 00000001624 12301751744 032701 0ustar000000000 0000000 # # 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. # info.module = HttpMime info.release = ${pom.version} info.timestamp = ${mvn.timestamp} # timestamp requires Maven 2.1 httpcomponents-client-4.3.3/httpmime/src/test/0040755 0000000 0000000 00000000000 12301751742 020213 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/test/java/0040755 0000000 0000000 00000000000 12301751742 021134 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/test/java/org/0040755 0000000 0000000 00000000000 12301751742 021723 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/test/java/org/apache/0040755 0000000 0000000 00000000000 12301751742 023144 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/test/java/org/apache/http/0040755 0000000 0000000 00000000000 12301751742 024123 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/test/java/org/apache/http/entity/0040755 0000000 0000000 00000000000 12301751742 025437 5ustar000000000 0000000 httpcomponents-client-4.3.3/httpmime/src/test/java/org/apache/http/entity/mime/0040755 0000000 0000000 00000000000 12301751742 026366 5ustar000000000 0000000 ././@LongLink0100644 0000000 0000000 00000000155 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/test/java/org/apache/http/entity/mime/TestMultipartContentBody.javahttpcomponents-client-4.3.3/httpmime/src/test/java/org/apache/http/entity/mime/TestMultipartContentB0100644 0000000 0000000 00000007364 12301751742 032576 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import java.io.ByteArrayInputStream; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.content.InputStreamBody; import org.apache.http.entity.mime.content.StringBody; import org.junit.Assert; import org.junit.Test; public class TestMultipartContentBody { @Test public void testStringBody() throws Exception { final StringBody b1 = new StringBody("text", ContentType.DEFAULT_TEXT); Assert.assertEquals(4, b1.getContentLength()); Assert.assertEquals("ISO-8859-1", b1.getCharset()); Assert.assertNull(b1.getFilename()); Assert.assertEquals("text/plain", b1.getMimeType()); Assert.assertEquals("text", b1.getMediaType()); Assert.assertEquals("plain", b1.getSubType()); Assert.assertEquals(MIME.ENC_8BIT, b1.getTransferEncoding()); final StringBody b2 = new StringBody("more text", ContentType.create("text/other", MIME.DEFAULT_CHARSET)); Assert.assertEquals(9, b2.getContentLength()); Assert.assertEquals(MIME.DEFAULT_CHARSET.name(), b2.getCharset()); Assert.assertNull(b2.getFilename()); Assert.assertEquals("text/other", b2.getMimeType()); Assert.assertEquals("text", b2.getMediaType()); Assert.assertEquals("other", b2.getSubType()); Assert.assertEquals(MIME.ENC_8BIT, b2.getTransferEncoding()); } @Test public void testInputStreamBody() throws Exception { final byte[] stuff = "Stuff".getBytes("US-ASCII"); final InputStreamBody b1 = new InputStreamBody(new ByteArrayInputStream(stuff), "stuff"); Assert.assertEquals(-1, b1.getContentLength()); Assert.assertNull(b1.getCharset()); Assert.assertEquals("stuff", b1.getFilename()); Assert.assertEquals("application/octet-stream", b1.getMimeType()); Assert.assertEquals("application", b1.getMediaType()); Assert.assertEquals("octet-stream", b1.getSubType()); Assert.assertEquals(MIME.ENC_BINARY, b1.getTransferEncoding()); final InputStreamBody b2 = new InputStreamBody( new ByteArrayInputStream(stuff), ContentType.create("some/stuff"), "stuff"); Assert.assertEquals(-1, b2.getContentLength()); Assert.assertNull(b2.getCharset()); Assert.assertEquals("stuff", b2.getFilename()); Assert.assertEquals("some/stuff", b2.getMimeType()); Assert.assertEquals("some", b2.getMediaType()); Assert.assertEquals("stuff", b2.getSubType()); Assert.assertEquals(MIME.ENC_BINARY, b2.getTransferEncoding()); } } ././@LongLink0100644 0000000 0000000 00000000157 12302131606 011630 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/test/java/org/apache/http/entity/mime/TestMultipartEntityBuilder.javahttpcomponents-client-4.3.3/httpmime/src/test/java/org/apache/http/entity/mime/TestMultipartEntityBu0100644 0000000 0000000 00000005651 12301751742 032622 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import java.io.ByteArrayInputStream; import java.io.File; import java.util.List; import org.apache.http.Consts; import org.junit.Assert; import org.junit.Test; public class TestMultipartEntityBuilder { @Test public void testBasics() throws Exception { final MultipartFormEntity entity = MultipartEntityBuilder.create().buildEntity(); Assert.assertNotNull(entity); Assert.assertTrue(entity.getMultipart() instanceof HttpStrictMultipart); Assert.assertEquals(0, entity.getMultipart().getBodyParts().size()); } @Test public void testMultipartOptions() throws Exception { final MultipartFormEntity entity = MultipartEntityBuilder.create() .setBoundary("blah-blah") .setCharset(Consts.UTF_8) .setLaxMode() .buildEntity(); Assert.assertNotNull(entity); Assert.assertTrue(entity.getMultipart() instanceof HttpBrowserCompatibleMultipart); Assert.assertEquals("blah-blah", entity.getMultipart().getBoundary()); Assert.assertEquals(Consts.UTF_8, entity.getMultipart().getCharset()); } @Test public void testAddBodyParts() throws Exception { final MultipartFormEntity entity = MultipartEntityBuilder.create() .addTextBody("p1", "stuff") .addBinaryBody("p2", new File("stuff")) .addBinaryBody("p3", new byte[] {}) .addBinaryBody("p4", new ByteArrayInputStream(new byte[] {})) .buildEntity(); Assert.assertNotNull(entity); final List bodyParts = entity.getMultipart().getBodyParts(); Assert.assertNotNull(bodyParts); Assert.assertEquals(4, bodyParts.size()); } } ././@LongLink0100644 0000000 0000000 00000000146 12302131606 011626 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/test/java/org/apache/http/entity/mime/TestMultipartForm.javahttpcomponents-client-4.3.3/httpmime/src/test/java/org/apache/http/entity/mime/TestMultipartForm.jav0100644 0000000 0000000 00000037106 12301751742 032541 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; import java.io.Writer; import java.nio.charset.Charset; import java.util.Arrays; import org.apache.http.Consts; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.InputStreamBody; import org.apache.http.entity.mime.content.StringBody; import org.junit.After; import org.junit.Assert; import org.junit.Test; public class TestMultipartForm { private File tmpfile; @After public void cleanup() { if (tmpfile != null) { tmpfile.delete(); } } @Test public void testMultipartFormStringParts() throws Exception { final FormBodyPart p1 = new FormBodyPart( "field1", new StringBody("this stuff", ContentType.DEFAULT_TEXT)); final FormBodyPart p2 = new FormBodyPart( "field2", new StringBody("that stuff", ContentType.create( ContentType.TEXT_PLAIN.getMimeType(), Consts.UTF_8))); final FormBodyPart p3 = new FormBodyPart( "field3", new StringBody("all kind of stuff", ContentType.DEFAULT_TEXT)); final HttpStrictMultipart multipart = new HttpStrictMultipart("form-data", null, "foo", Arrays.asList(p1, p2, p3)); final ByteArrayOutputStream out = new ByteArrayOutputStream(); multipart.writeTo(out); out.close(); final String expected = "--foo\r\n" + "Content-Disposition: form-data; name=\"field1\"\r\n" + "Content-Type: text/plain; charset=ISO-8859-1\r\n" + "Content-Transfer-Encoding: 8bit\r\n" + "\r\n" + "this stuff\r\n" + "--foo\r\n" + "Content-Disposition: form-data; name=\"field2\"\r\n" + "Content-Type: text/plain; charset=UTF-8\r\n" + "Content-Transfer-Encoding: 8bit\r\n" + "\r\n" + "that stuff\r\n" + "--foo\r\n" + "Content-Disposition: form-data; name=\"field3\"\r\n" + "Content-Type: text/plain; charset=ISO-8859-1\r\n" + "Content-Transfer-Encoding: 8bit\r\n" + "\r\n" + "all kind of stuff\r\n" + "--foo--\r\n"; final String s = out.toString("US-ASCII"); Assert.assertEquals(expected, s); Assert.assertEquals(s.length(), multipart.getTotalLength()); } @Test public void testMultipartFormCustomContentType() throws Exception { final FormBodyPart p1 = new FormBodyPart( "field1", new StringBody("this stuff", ContentType.DEFAULT_TEXT)); final FormBodyPart p2 = new FormBodyPart( "field2", new StringBody("that stuff", ContentType.parse("stuff/plain; param=value"))); final HttpStrictMultipart multipart = new HttpStrictMultipart("form-data", null, "foo", Arrays.asList(p1, p2)); final ByteArrayOutputStream out = new ByteArrayOutputStream(); multipart.writeTo(out); out.close(); final String expected = "--foo\r\n" + "Content-Disposition: form-data; name=\"field1\"\r\n" + "Content-Type: text/plain; charset=ISO-8859-1\r\n" + "Content-Transfer-Encoding: 8bit\r\n" + "\r\n" + "this stuff\r\n" + "--foo\r\n" + "Content-Disposition: form-data; name=\"field2\"\r\n" + "Content-Type: stuff/plain; param=value\r\n" + "Content-Transfer-Encoding: 8bit\r\n" + "\r\n" + "that stuff\r\n" + "--foo--\r\n"; final String s = out.toString("US-ASCII"); Assert.assertEquals(expected, s); Assert.assertEquals(s.length(), multipart.getTotalLength()); } @Test public void testMultipartFormBinaryParts() throws Exception { tmpfile = File.createTempFile("tmp", ".bin"); final Writer writer = new FileWriter(tmpfile); try { writer.append("some random whatever"); } finally { writer.close(); } final FormBodyPart p1 = new FormBodyPart( "field1", new FileBody(tmpfile)); final FormBodyPart p2 = new FormBodyPart( "field2", new InputStreamBody(new FileInputStream(tmpfile), "file.tmp")); final HttpStrictMultipart multipart = new HttpStrictMultipart("form-data", null, "foo", Arrays.asList(p1, p2)); final ByteArrayOutputStream out = new ByteArrayOutputStream(); multipart.writeTo(out); out.close(); final String expected = "--foo\r\n" + "Content-Disposition: form-data; name=\"field1\"; " + "filename=\"" + tmpfile.getName() + "\"\r\n" + "Content-Type: application/octet-stream\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n" + "some random whatever\r\n" + "--foo\r\n" + "Content-Disposition: form-data; name=\"field2\"; " + "filename=\"file.tmp\"\r\n" + "Content-Type: application/octet-stream\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n" + "some random whatever\r\n" + "--foo--\r\n"; final String s = out.toString("US-ASCII"); Assert.assertEquals(expected, s); Assert.assertEquals(-1, multipart.getTotalLength()); } @Test public void testMultipartFormStrict() throws Exception { tmpfile = File.createTempFile("tmp", ".bin"); final Writer writer = new FileWriter(tmpfile); try { writer.append("some random whatever"); } finally { writer.close(); } final FormBodyPart p1 = new FormBodyPart( "field1", new FileBody(tmpfile)); final FormBodyPart p2 = new FormBodyPart( "field2", new FileBody(tmpfile, ContentType.create("text/plain", "ANSI_X3.4-1968"), "test-file")); final FormBodyPart p3 = new FormBodyPart( "field3", new InputStreamBody(new FileInputStream(tmpfile), "file.tmp")); final HttpStrictMultipart multipart = new HttpStrictMultipart("form-data", null, "foo", Arrays.asList(p1, p2, p3)); final ByteArrayOutputStream out = new ByteArrayOutputStream(); multipart.writeTo(out); out.close(); final String expected = "--foo\r\n" + "Content-Disposition: form-data; name=\"field1\"; " + "filename=\"" + tmpfile.getName() + "\"\r\n" + "Content-Type: application/octet-stream\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n" + "some random whatever\r\n" + "--foo\r\n" + "Content-Disposition: form-data; name=\"field2\"; " + "filename=\"test-file\"\r\n" + "Content-Type: text/plain; charset=US-ASCII\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n" + "some random whatever\r\n" + "--foo\r\n" + "Content-Disposition: form-data; name=\"field3\"; " + "filename=\"file.tmp\"\r\n" + "Content-Type: application/octet-stream\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n" + "some random whatever\r\n" + "--foo--\r\n"; final String s = out.toString("US-ASCII"); Assert.assertEquals(expected, s); Assert.assertEquals(-1, multipart.getTotalLength()); } @Test public void testMultipartFormRFC6532() throws Exception { tmpfile = File.createTempFile("tmp", ".bin"); final Writer writer = new FileWriter(tmpfile); try { writer.append("some random whatever"); } finally { writer.close(); } final FormBodyPart p1 = new FormBodyPart( "field1\u0414", new FileBody(tmpfile)); final FormBodyPart p2 = new FormBodyPart( "field2", new FileBody(tmpfile, ContentType.create("text/plain", "ANSI_X3.4-1968"), "test-file")); final FormBodyPart p3 = new FormBodyPart( "field3", new InputStreamBody(new FileInputStream(tmpfile), "file.tmp")); final HttpRFC6532Multipart multipart = new HttpRFC6532Multipart("form-data", null, "foo", Arrays.asList(p1, p2, p3)); final ByteArrayOutputStream out = new ByteArrayOutputStream(); multipart.writeTo(out); out.close(); final String expected = "--foo\r\n" + "Content-Disposition: form-data; name=\"field1\u0414\"; " + "filename=\"" + tmpfile.getName() + "\"\r\n" + "Content-Type: application/octet-stream\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n" + "some random whatever\r\n" + "--foo\r\n" + "Content-Disposition: form-data; name=\"field2\"; " + "filename=\"test-file\"\r\n" + "Content-Type: text/plain; charset=US-ASCII\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n" + "some random whatever\r\n" + "--foo\r\n" + "Content-Disposition: form-data; name=\"field3\"; " + "filename=\"file.tmp\"\r\n" + "Content-Type: application/octet-stream\r\n" + "Content-Transfer-Encoding: binary\r\n" + "\r\n" + "some random whatever\r\n" + "--foo--\r\n"; final String s = out.toString("UTF-8"); Assert.assertEquals(expected, s); Assert.assertEquals(-1, multipart.getTotalLength()); } private static final int SWISS_GERMAN_HELLO [] = { 0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4 }; private static final int RUSSIAN_HELLO [] = { 0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438, 0x432, 0x435, 0x442 }; private static String constructString(final int [] unicodeChars) { final StringBuilder buffer = new StringBuilder(); if (unicodeChars != null) { for (final int unicodeChar : unicodeChars) { buffer.append((char)unicodeChar); } } return buffer.toString(); } @Test public void testMultipartFormBrowserCompatibleNonASCIIHeaders() throws Exception { final String s1 = constructString(SWISS_GERMAN_HELLO); final String s2 = constructString(RUSSIAN_HELLO); tmpfile = File.createTempFile("tmp", ".bin"); final Writer writer = new FileWriter(tmpfile); try { writer.append("some random whatever"); } finally { writer.close(); } final FormBodyPart p1 = new FormBodyPart( "field1", new InputStreamBody(new FileInputStream(tmpfile), s1 + ".tmp")); final FormBodyPart p2 = new FormBodyPart( "field2", new InputStreamBody(new FileInputStream(tmpfile), s2 + ".tmp")); final HttpBrowserCompatibleMultipart multipart = new HttpBrowserCompatibleMultipart( "form-data", Consts.UTF_8, "foo", Arrays.asList(p1, p2)); final ByteArrayOutputStream out = new ByteArrayOutputStream(); multipart.writeTo(out); out.close(); final String expected = "--foo\r\n" + "Content-Disposition: form-data; name=\"field1\"; " + "filename=\"" + s1 + ".tmp\"\r\n" + "Content-Type: application/octet-stream\r\n" + "\r\n" + "some random whatever\r\n" + "--foo\r\n" + "Content-Disposition: form-data; name=\"field2\"; " + "filename=\"" + s2 + ".tmp\"\r\n" + "Content-Type: application/octet-stream\r\n" + "\r\n" + "some random whatever\r\n" + "--foo--\r\n"; final String s = out.toString("UTF-8"); Assert.assertEquals(expected, s); Assert.assertEquals(-1, multipart.getTotalLength()); } @Test public void testMultipartFormStringPartsMultiCharsets() throws Exception { final String s1 = constructString(SWISS_GERMAN_HELLO); final String s2 = constructString(RUSSIAN_HELLO); final FormBodyPart p1 = new FormBodyPart( "field1", new StringBody(s1, ContentType.create("text/plain", Charset.forName("ISO-8859-1")))); final FormBodyPart p2 = new FormBodyPart( "field2", new StringBody(s2, ContentType.create("text/plain", Charset.forName("KOI8-R")))); final HttpStrictMultipart multipart = new HttpStrictMultipart("form-data", null, "foo", Arrays.asList(p1, p2)); final ByteArrayOutputStream out1 = new ByteArrayOutputStream(); multipart.writeTo(out1); out1.close(); final ByteArrayOutputStream out2 = new ByteArrayOutputStream(); out2.write(( "--foo\r\n" + "Content-Disposition: form-data; name=\"field1\"\r\n" + "Content-Type: text/plain; charset=ISO-8859-1\r\n" + "Content-Transfer-Encoding: 8bit\r\n" + "\r\n").getBytes("US-ASCII")); out2.write(s1.getBytes("ISO-8859-1")); out2.write(("\r\n" + "--foo\r\n" + "Content-Disposition: form-data; name=\"field2\"\r\n" + "Content-Type: text/plain; charset=KOI8-R\r\n" + "Content-Transfer-Encoding: 8bit\r\n" + "\r\n").getBytes("US-ASCII")); out2.write(s2.getBytes("KOI8-R")); out2.write(("\r\n" + "--foo--\r\n").getBytes("US-ASCII")); out2.close(); final byte[] actual = out1.toByteArray(); final byte[] expected = out2.toByteArray(); Assert.assertEquals(expected.length, actual.length); for (int i = 0; i < actual.length; i++) { Assert.assertEquals(expected[i], actual[i]); } Assert.assertEquals(expected.length, multipart.getTotalLength()); } } ././@LongLink0100644 0000000 0000000 00000000160 12302131606 011622 Lustar 0000000 0000000 httpcomponents-client-4.3.3/httpmime/src/test/java/org/apache/http/entity/mime/TestMultipartFormHttpEntity.javahttpcomponents-client-4.3.3/httpmime/src/test/java/org/apache/http/entity/mime/TestMultipartFormHttp0100644 0000000 0000000 00000012423 12301751742 032615 0ustar000000000 0000000 /* * ==================================================================== * 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ package org.apache.http.entity.mime; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.content.InputStreamBody; import org.junit.Assert; import org.junit.Test; public class TestMultipartFormHttpEntity { @Test public void testExplictContractorParams() throws Exception { final HttpEntity entity = MultipartEntityBuilder.create() .setLaxMode() .setBoundary("whatever") .setCharset(MIME.UTF8_CHARSET) .build(); Assert.assertNull(entity.getContentEncoding()); Assert.assertNotNull(entity.getContentType()); final Header header = entity.getContentType(); final HeaderElement[] elems = header.getElements(); Assert.assertNotNull(elems); Assert.assertEquals(1, elems.length); final HeaderElement elem = elems[0]; Assert.assertEquals("multipart/form-data", elem.getName()); final NameValuePair p1 = elem.getParameterByName("boundary"); Assert.assertNotNull(p1); Assert.assertEquals("whatever", p1.getValue()); final NameValuePair p2 = elem.getParameterByName("charset"); Assert.assertNotNull(p2); Assert.assertEquals("UTF-8", p2.getValue()); } @Test public void testImplictContractorParams() throws Exception { final HttpEntity entity = MultipartEntityBuilder.create().build(); Assert.assertNull(entity.getContentEncoding()); Assert.assertNotNull(entity.getContentType()); final Header header = entity.getContentType(); final HeaderElement[] elems = header.getElements(); Assert.assertNotNull(elems); Assert.assertEquals(1, elems.length); final HeaderElement elem = elems[0]; Assert.assertEquals("multipart/form-data", elem.getName()); final NameValuePair p1 = elem.getParameterByName("boundary"); Assert.assertNotNull(p1); final String boundary = p1.getValue(); Assert.assertNotNull(boundary); Assert.assertTrue(boundary.length() >= 30); Assert.assertTrue(boundary.length() <= 40); final NameValuePair p2 = elem.getParameterByName("charset"); Assert.assertNull(p2); } @Test public void testRepeatable() throws Exception { final HttpEntity entity = MultipartEntityBuilder.create() .addTextBody("p1", "blah blah", ContentType.DEFAULT_TEXT) .addTextBody("p2", "yada yada", ContentType.DEFAULT_TEXT) .build(); Assert.assertTrue(entity.isRepeatable()); Assert.assertFalse(entity.isChunked()); Assert.assertFalse(entity.isStreaming()); final long len = entity.getContentLength(); Assert.assertTrue(len == entity.getContentLength()); ByteArrayOutputStream out = new ByteArrayOutputStream(); entity.writeTo(out); out.close(); byte[] bytes = out.toByteArray(); Assert.assertNotNull(bytes); Assert.assertTrue(bytes.length == len); Assert.assertTrue(len == entity.getContentLength()); out = new ByteArrayOutputStream(); entity.writeTo(out); out.close(); bytes = out.toByteArray(); Assert.assertNotNull(bytes); Assert.assertTrue(bytes.length == len); } @Test public void testNonRepeatable() throws Exception { final HttpEntity entity = MultipartEntityBuilder.create() .addPart("p1", new InputStreamBody( new ByteArrayInputStream("blah blah".getBytes()), ContentType.DEFAULT_BINARY)) .addPart("p2", new InputStreamBody( new ByteArrayInputStream("yada yada".getBytes()), ContentType.DEFAULT_BINARY)) .build(); Assert.assertFalse(entity.isRepeatable()); Assert.assertTrue(entity.isChunked()); Assert.assertTrue(entity.isStreaming()); Assert.assertTrue(entity.getContentLength() == -1); } } httpcomponents-client-4.3.3/src/0040755 0000000 0000000 00000000000 12301751744 015407 5ustar000000000 0000000 httpcomponents-client-4.3.3/src/docbkx/0040755 0000000 0000000 00000000000 12301751746 016663 5ustar000000000 0000000 httpcomponents-client-4.3.3/src/docbkx/advanced.xml0100644 0000000 0000000 00000034163 12301751746 021156 0ustar000000000 0000000 Advanced topics
Custom client connections In certain situations it may be necessary to customize the way HTTP messages get transmitted across the wire beyond what is possible using HTTP parameters in order to be able to deal non-standard, non-compliant behaviours. For instance, for web crawlers it may be necessary to force HttpClient into accepting malformed response heads in order to salvage the content of the messages. Usually the process of plugging in a custom message parser or a custom connection implementation involves several steps: Provide a custom LineParser / LineFormatter interface implementation. Implement message parsing / formatting logic as required. Provide a custom HttpConnectionFactory implementation. Replace default request writer and / or response parser with custom ones as required. connFactory = new ManagedHttpClientConnectionFactory( new DefaultHttpRequestWriterFactory(), new DefaultHttpResponseParserFactory( new MyLineParser(), new DefaultHttpResponseFactory())); ]]> Configure HttpClient to use the custom connection factory.
Stateful HTTP connections While HTTP specification assumes that session state information is always embedded in HTTP messages in the form of HTTP cookies and therefore HTTP connections are always stateless, this assumption does not always hold true in real life. There are cases when HTTP connections are created with a particular user identity or within a particular security context and therefore cannot be shared with other users and can be reused by the same user only. Examples of such stateful HTTP connections are NTLM authenticated connections and SSL connections with client certificate authentication.
User token handler HttpClient relies on UserTokenHandler interface to determine if the given execution context is user specific or not. The token object returned by this handler is expected to uniquely identify the current user if the context is user specific or to be null if the context does not contain any resources or details specific to the current user. The user token will be used to ensure that user specific resources will not be shared with or reused by other users. The default implementation of the UserTokenHandler interface uses an instance of Principal class to represent a state object for HTTP connections, if it can be obtained from the given execution context. DefaultUserTokenHandler will use the user principle of connection based authentication schemes such as NTLM or that of the SSL session with client authentication turned on. If both are unavailable, null token will be returned. Users can provide a custom implementation if the default one does not satisfy their needs:
Persistent stateful connections Please note that a persistent connection that carries a state object can be reused only if the same state object is bound to the execution context when requests are executed. So, it is really important to ensure the either same context is reused for execution of subsequent HTTP requests by the same user or the user token is bound to the context prior to request execution.
Using the FutureRequestExecutionService Using the FutureRequestExecutionService, you can schedule http calls and treat the response as a Future. This is useful when e.g. making multiple calls to a web service. The advantage of using the FutureRequestExecutionService is that you can use multiple threads to schedule requests concurrently, set timeouts on the tasks, or cancel them when a response is no longer necessary. FutureRequestExecutionService wraps the request with a HttpRequestFutureTask, which extends FutureTask. This class allows you to cancel the task as well as keep track of various metrics such as request duration.
Creating the FutureRequestExecutionService The constructor for the futureRequestExecutionService takes any existing httpClient instance and an ExecutorService instance. When configuring both, it is important to align the maximum number of connections with the number of threads you are going to use. When there are more threads than connections, the connections may start timing out because there are no available connections. When there are more connections than threads, the futureRequestExecutionService will not use all of them
Scheduling requests To schedule a request, simply provide a HttpUriRequest, HttpContext, and a ResponseHandler. Because the request is processed by the executor service, a ResponseHandler is mandatory. { public Boolean handleResponse( final HttpResponse response) throws ClientProtocolException, IOException { return response.getStatusLine().getStatusCode() == 200; } } HttpRequestFutureTask task = futureRequestExecutionService.execute( new HttpGet("http://www.google.com"), HttpClientContext.create(), new OkidokiHandler()); // blocks until the request complete and then returns true if you can connect to Google boolean ok=task.get(); ]]>
Canceling tasks Scheduled tasks may be cancelled. If the task is not yet executing but merely queued for execution, it simply will never execute. If it is executing and the mayInterruptIfRunning parameter is set to true, abort() will be called on the request; otherwise the response will simply be ignored but the request will be allowed to complete normally. Any subsequent calls to task.get() will fail with an IllegalStateException. It should be noticed that canceling tasks merely frees up the client side resources. The request may actually be handled normally on the server side.
Callbacks Instead of manually calling task.get(), you can also use a FutureCallback instance that gets callbacks when the request completes. This is the same interface as is used in HttpAsyncClient { public void failed(final Exception ex) { // do something } public void completed(final Boolean result) { // do something } public void cancelled() { // do something } } HttpRequestFutureTask task = futureRequestExecutionService.execute( new HttpGet("http://www.google.com"), HttpClientContext.create(), new OkidokiHandler(), new MyCallback()); ]]>
Metrics FutureRequestExecutionService is typically used in applications that make large amounts of web service calls. To facilitate e.g. monitoring or configuration tuning, the FutureRequestExecutionService keeps track of several metrics. Each HttpRequestFutureTask provides methods to get the time the task was scheduled, started, and ended. Additionally, request and task duration are available as well. These metrics are aggregated in the FutureRequestExecutionService in a FutureRequestExecutionMetrics instance that may be accessed through FutureRequestExecutionService.metrics().
httpcomponents-client-4.3.3/src/docbkx/authentication.xml0100644 0000000 0000000 00000067340 12301751746 022433 0ustar000000000 0000000 HTTP authentication HttpClient provides full support for authentication schemes defined by the HTTP standard specification as well as a number of widely used non-standard authentication schemes such as NTLM and SPNEGO.
User credentials Any process of user authentication requires a set of credentials that can be used to establish user identity. In the simplest form user credentials can be just a user name / password pair. UsernamePasswordCredentials represents a set of credentials consisting of a security principal and a password in clear text. This implementation is sufficient for standard authentication schemes defined by the HTTP standard specification. stdout > NTCredentials is a Microsoft Windows specific implementation that includes in addition to the user name / password pair a set of additional Windows specific attributes such as the name of the user domain. In a Microsoft Windows network the same user can belong to multiple domains each with a different set of authorizations. stdout >
Authentication schemes The AuthScheme interface represents an abstract challenge-response oriented authentication scheme. An authentication scheme is expected to support the following functions: Parse and process the challenge sent by the target server in response to request for a protected resource. Provide properties of the processed challenge: the authentication scheme type and its parameters, such the realm this authentication scheme is applicable to, if available Generate the authorization string for the given set of credentials and the HTTP request in response to the actual authorization challenge. Please note that authentication schemes may be stateful involving a series of challenge-response exchanges. HttpClient ships with several AuthScheme implementations: Basic: Basic authentication scheme as defined in RFC 2617. This authentication scheme is insecure, as the credentials are transmitted in clear text. Despite its insecurity Basic authentication scheme is perfectly adequate if used in combination with the TLS/SSL encryption. Digest Digest authentication scheme as defined in RFC 2617. Digest authentication scheme is significantly more secure than Basic and can be a good choice for those applications that do not want the overhead of full transport security through TLS/SSL encryption. NTLM: NTLM is a proprietary authentication scheme developed by Microsoft and optimized for Windows platforms. NTLM is believed to be more secure than Digest. SPNEGO: SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) is a GSSAPI "pseudo mechanism" that is used to negotiate one of a number of possible real mechanisms. SPNEGO's most visible use is in Microsoft's HTTP Negotiate authentication extension. The negotiable sub-mechanisms include NTLM and Kerberos supported by Active Directory. At present HttpClient only supports the Kerberos sub-mechanism. Kerberos: Kerberos authentication implementation.
Credentials provider Credentials providers are intended to maintain a set of user credentials and to be able to produce user credentials for a particular authentication scope. Authentication scope consists of a host name, a port number, a realm name and an authentication scheme name. When registering credentials with the credentials provider one can provide a wild card (any host, any port, any realm, any scheme) instead of a concrete attribute value. The credentials provider is then expected to be able to find the closest match for a particular scope if the direct match cannot be found. HttpClient can work with any physical representation of a credentials provider that implements the CredentialsProvider interface. The default CredentialsProvider implementation called BasicCredentialsProvider is a simple implementation backed by a java.util.HashMap. stdout >
HTTP authentication and execution context HttpClient relies on the AuthState class to keep track of detailed information about the state of the authentication process. HttpClient creates two instances of AuthState in the course of HTTP request execution: one for target host authentication and another one for proxy authentication. In case the target server or the proxy require user authentication the respective AuthScope instance will be populated with the AuthScope, AuthScheme and Crednetials used during the authentication process. The AuthState can be examined in order to find out what kind of authentication was requested, whether a matching AuthScheme implementation was found and whether the credentials provider managed to find user credentials for the given authentication scope. In the course of HTTP request execution HttpClient adds the following authentication related objects to the execution context: Lookup instance representing the actual authentication scheme registry. The value of this attribute set in the local context takes precedence over the default one. CredentialsProvider instance representing the actual credentials provider. The value of this attribute set in the local context takes precedence over the default one. AuthState instance representing the actual target authentication state. The value of this attribute set in the local context takes precedence over the default one. AuthState instance representing the actual proxy authentication state. The value of this attribute set in the local context takes precedence over the default one. AuthCache instance representing the actual authentication data cache. The value of this attribute set in the local context takes precedence over the default one. The local HttpContext object can be used to customize the HTTP authentication context prior to request execution, or to examine its state after the request has been executed: CredentialsProvider credsProvider = <...> Lookup authRegistry = <...> AuthCache authCache = <...> HttpClientContext context = HttpClientContext.create(); context.setCredentialsProvider(credsProvider); context.setAuthSchemeRegistry(authRegistry); context.setAuthCache(authCache); HttpGet httpget = new HttpGet("http://somehost/"); CloseableHttpResponse response1 = httpclient.execute(httpget, context); <...> AuthState proxyAuthState = context.getProxyAuthState(); System.out.println("Proxy auth state: " + proxyAuthState.getState()); System.out.println("Proxy auth scheme: " + proxyAuthState.getAuthScheme()); System.out.println("Proxy auth credentials: " + proxyAuthState.getCredentials()); AuthState targetAuthState = context.getTargetAuthState(); System.out.println("Target auth state: " + targetAuthState.getState()); System.out.println("Target auth scheme: " + targetAuthState.getAuthScheme()); System.out.println("Target auth credentials: " + targetAuthState.getCredentials()); ]]>
Caching of authentication data As of version 4.1 HttpClient automatically caches information about hosts it has successfully authenticated with. Please note that one must use the same execution context to execute logically related requests in order for cached authentication data to propagate from one request to another. Authentication data will be lost as soon as the execution context goes out of scope.
Preemptive authentication HttpClient does not support preemptive authentication out of the box, because if misused or used incorrectly the preemptive authentication can lead to significant security issues, such as sending user credentials in clear text to an unauthorized third party. Therefore, users are expected to evaluate potential benefits of preemptive authentication versus security risks in the context of their specific application environment. Nonetheless one can configure HttpClient to authenticate preemptively by prepopulating the authentication data cache. HttpHost targetHost = new HttpHost("localhost", 80, "http"); CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( new AuthScope(targetHost.getHostName(), targetHost.getPort()), new UsernamePasswordCredentials("username", "password")); // Create AuthCache instance AuthCache authCache = new BasicAuthCache(); // Generate BASIC scheme object and add it to the local auth cache BasicScheme basicAuth = new BasicScheme(); authCache.put(targetHost, basicAuth); // Add AuthCache to the execution context HttpClientContext context = HttpClientContext.create(); context.setCredentialsProvider(credsProvider); context.setAuthCache(authCache); HttpGet httpget = new HttpGet("/"); for (int i = 0; i < 3; i++) { CloseableHttpResponse response = httpclient.execute( targetHost, httpget, context); try { HttpEntity entity = response.getEntity(); } finally { response.close(); } } ]]>
NTLM Authentication As of version 4.1 HttpClient provides full support for NTLMv1, NTLMv2, and NTLM2 Session authentication out of the box. One can still continue using an external NTLM engine such as JCIFS library developed by the Samba project as a part of their Windows interoperability suite of programs.
NTLM connection persistence The NTLM authentication scheme is significantly more expensive in terms of computational overhead and performance impact than the standard Basic and Digest schemes. This is likely to be one of the main reasons why Microsoft chose to make NTLM authentication scheme stateful. That is, once authenticated, the user identity is associated with that connection for its entire life span. The stateful nature of NTLM connections makes connection persistence more complex, as for the obvious reason persistent NTLM connections may not be re-used by users with a different user identity. The standard connection managers shipped with HttpClient are fully capable of managing stateful connections. However, it is critically important that logically related requests within the same session use the same execution context in order to make them aware of the current user identity. Otherwise, HttpClient will end up creating a new HTTP connection for each HTTP request against NTLM protected resources. For detailed discussion on stateful HTTP connections please refer to this section. As NTLM connections are stateful it is generally recommended to trigger NTLM authentication using a relatively cheap method, such as GET or HEAD, and re-use the same connection to execute more expensive methods, especially those enclose a request entity, such as POST or PUT. CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(AuthScope.ANY, new NTCredentials("user", "pwd", "myworkstation", "microsoft.com")); HttpHost target = new HttpHost("www.microsoft.com", 80, "http"); // Make sure the same context is used to execute logically related requests HttpClientContext context = HttpClientContext.create(); context.setCredentialsProvider(credsProvider); // Execute a cheap method first. This will trigger NTLM authentication HttpGet httpget = new HttpGet("/ntlm-protected/info"); CloseableHttpResponse response1 = httpclient.execute(target, httpget, context); try { HttpEntity entity1 = response1.getEntity(); } finally { response1.close(); } // Execute an expensive method next reusing the same context (and connection) HttpPost httppost = new HttpPost("/ntlm-protected/form"); httppost.setEntity(new StringEntity("lots and lots of data")); CloseableHttpResponse response2 = httpclient.execute(target, httppost, context); try { HttpEntity entity2 = response2.getEntity(); } finally { response2.close(); } ]]>
<literal>SPNEGO</literal>/Kerberos Authentication The SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) is designed to allow for authentication to services when neither end knows what the other can use/provide. It is most commonly used to do Kerberos authentication. It can wrap other mechanisms, however the current version in HttpClient is designed solely with Kerberos in mind. Client Web Browser does HTTP GET for resource. Web server returns HTTP 401 status and a header: WWW-Authenticate: Negotiate Client generates a NegTokenInit, base64 encodes it, and resubmits the GET with an Authorization header: Authorization: Negotiate <base64 encoding>. Server decodes the NegTokenInit, extracts the supported MechTypes (only Kerberos V5 in our case), ensures it is one of the expected ones, and then extracts the MechToken (Kerberos Token) and authenticates it. If more processing is required another HTTP 401 is returned to the client with more data in the the WWW-Authenticate header. Client takes the info and generates another token passing this back in the Authorization header until complete. When the client has been authenticated the Web server should return the HTTP 200 status, a final WWW-Authenticate header and the page content.
<literal>SPNEGO</literal> support in HttpClient The SPNEGO authentication scheme is compatible with Sun Java versions 1.5 and up. However the use of Java >= 1.6 is strongly recommended as it supports SPNEGO authentication more completely. The Sun JRE provides the supporting classes to do nearly all the Kerberos and SPNEGO token handling. This means that a lot of the setup is for the GSS classes. The SPNegoScheme is a simple class to handle marshalling the tokens and reading and writing the correct headers. The best way to start is to grab the KerberosHttpClient.java file in examples and try and get it to work. There are a lot of issues that can happen but if lucky it'll work without too much of a problem. It should also provide some output to debug with. In Windows it should default to using the logged in credentials; this can be overridden by using 'kinit' e.g. $JAVA_HOME\bin\kinit testuser@AD.EXAMPLE.NET, which is very helpful for testing and debugging issues. Remove the cache file created by kinit to revert back to the windows Kerberos cache. Make sure to list domain_realms in the krb5.conf file. This is a major source of problems.
GSS/Java Kerberos Setup This documentation assumes you are using Windows but much of the information applies to Unix as well. The org.ietf.jgss classes have lots of possible configuration parameters, mainly in the krb5.conf/krb5.ini file. Some more info on the format at http://web.mit.edu/kerberos/krb5-1.4/krb5-1.4.1/doc/krb5-admin/krb5.conf.html.
<literal>login.conf</literal> file The following configuration is a basic setup that works in Windows XP against both IIS and JBoss Negotiation modules. The system property java.security.auth.login.config can be used to point at the login.conf file. login.conf content may look like the following:
<literal>krb5.conf</literal> / <literal>krb5.ini</literal> file If unspecified, the system default will be used. Override if needed by setting the system property java.security.krb5.conf to point to a custom krb5.conf file. krb5.conf content may look like the following:
Windows Specific configuration To allow Windows to use the current user's tickets, the system property javax.security.auth.useSubjectCredsOnly must be set to false and the Windows registry key allowtgtsessionkey should be added and set correctly to allow session keys to be sent in the Kerberos Ticket-Granting Ticket. On the Windows Server 2003 and Windows 2000 SP4, here is the required registry setting: Here is the location of the registry setting on Windows XP SP2:
httpcomponents-client-4.3.3/src/docbkx/caching.xml0100644 0000000 0000000 00000026254 12301751746 021007 0ustar000000000 0000000 HTTP Caching
General Concepts HttpClient Cache provides an HTTP/1.1-compliant caching layer to be used with HttpClient--the Java equivalent of a browser cache. The implementation follows the Chain of Responsibility design pattern, where the caching HttpClient implementation can serve a drop-in replacement for the default non-caching HttpClient implementation; requests that can be satisfied entirely from the cache will not result in actual origin requests. Stale cache entries are automatically validated with the origin where possible, using conditional GETs and the If-Modified-Since and/or If-None-Match request headers. HTTP/1.1 caching in general is designed to be semantically transparent; that is, a cache should not change the meaning of the request-response exchange between client and server. As such, it should be safe to drop a caching HttpClient into an existing compliant client-server relationship. Although the caching module is part of the client from an HTTP protocol point of view, the implementation aims to be compatible with the requirements placed on a transparent caching proxy. Finally, caching HttpClient includes support the Cache-Control extensions specified by RFC 5861 (stale-if-error and stale-while-revalidate). When caching HttpClient executes a request, it goes through the following flow: Check the request for basic compliance with the HTTP 1.1 protocol and attempt to correct the request. Flush any cache entries which would be invalidated by this request. Determine if the current request would be servable from cache. If not, directly pass through the request to the origin server and return the response, after caching it if appropriate. If it was a a cache-servable request, it will attempt to read it from the cache. If it is not in the cache, call the origin server and cache the response, if appropriate. If the cached response is suitable to be served as a response, construct a BasicHttpResponse containing a ByteArrayEntity and return it. Otherwise, attempt to revalidate the cache entry against the origin server. In the case of a cached response which cannot be revalidated, call the origin server and cache the response, if appropriate. When caching HttpClient receives a response, it goes through the following flow: Examining the response for protocol compliance Determine whether the response is cacheable If it is cacheable, attempt to read up to the maximum size allowed in the configuration and store it in the cache. If the response is too large for the cache, reconstruct the partially consumed response and return it directly without caching it. It is important to note that caching HttpClient is not, itself, a different implementation of HttpClient, but that it works by inserting itself as an additonal processing component to the request execution pipeline.
RFC-2616 Compliance We believe HttpClient Cache is unconditionally compliant with RFC-2616. That is, wherever the specification indicates MUST, MUST NOT, SHOULD, or SHOULD NOT for HTTP caches, the caching layer attempts to behave in a way that satisfies those requirements. This means the caching module won't produce incorrect behavior when you drop it in.
Example Usage This is a simple example of how to set up a basic caching HttpClient. As configured, it will store a maximum of 1000 cached objects, each of which may have a maximum body size of 8192 bytes. The numbers selected here are for example only and not intended to be prescriptive or considered as recommendations.
Configuration The caching HttpClient inherits all configuration options and parameters of the default non-caching implementation (this includes setting options like timeouts and connection pool sizes). For caching-specific configuration, you can provide a CacheConfig instance to customize behavior across the following areas: Cache size. If the backend storage supports these limits, you can specify the maximum number of cache entries as well as the maximum cacheable response body size. Public/private caching. By default, the caching module considers itself to be a shared (public) cache, and will not, for example, cache responses to requests with Authorization headers or responses marked with "Cache-Control: private". If, however, the cache is only going to be used by one logical "user" (behaving similarly to a browser cache), then you will want to turn off the shared cache setting. Heuristic caching.Per RFC2616, a cache MAY cache certain cache entries even if no explicit cache control headers are set by the origin. This behavior is off by default, but you may want to turn this on if you are working with an origin that doesn't set proper headers but where you still want to cache the responses. You will want to enable heuristic caching, then specify either a default freshness lifetime and/or a fraction of the time since the resource was last modified. See Sections 13.2.2 and 13.2.4 of the HTTP/1.1 RFC for more details on heuristic caching. Background validation. The cache module supports the stale-while-revalidate directive of RFC5861, which allows certain cache entry revalidations to happen in the background. You may want to tweak the settings for the minimum and maximum number of background worker threads, as well as the maximum time they can be idle before being reclaimed. You can also control the size of the queue used for revalidations when there aren't enough workers to keep up with demand.
Storage Backends The default implementation of caching HttpClient stores cache entries and cached response bodies in memory in the JVM of your application. While this offers high performance, it may not be appropriate for your application due to the limitation on size or because the cache entries are ephemeral and don't survive an application restart. The current release includes support for storing cache entries using EhCache and memcached implementations, which allow for spilling cache entries to disk or storing them in an external process. If none of those options are suitable for your application, it is possible to provide your own storage backend by implementing the HttpCacheStorage interface and then supplying that to caching HttpClient at construction time. In this case, the cache entries will be stored using your scheme but you will get to reuse all of the logic surrounding HTTP/1.1 compliance and cache handling. Generally speaking, it should be possible to create an HttpCacheStorage implementation out of anything that supports a key/value store (similar to the Java Map interface) with the ability to apply atomic updates. Finally, with some extra efforts it's entirely possible to set up a multi-tier caching hierarchy; for example, wrapping an in-memory caching HttpClient around one that stores cache entries on disk or remotely in memcached, following a pattern similar to virtual memory, L1/L2 processor caches, etc.
httpcomponents-client-4.3.3/src/docbkx/connmgmt.xml0100644 0000000 0000000 00000073343 12301751746 021236 0ustar000000000 0000000 Connection management
Connection persistence The process of establishing a connection from one host to another is quite complex and involves multiple packet exchanges between two endpoints, which can be quite time consuming. The overhead of connection handshaking can be significant, especially for small HTTP messages. One can achieve a much higher data throughput if open connections can be re-used to execute multiple requests. HTTP/1.1 states that HTTP connections can be re-used for multiple requests per default. HTTP/1.0 compliant endpoints can also use a mechanism to explicitly communicate their preference to keep connection alive and use it for multiple requests. HTTP agents can also keep idle connections alive for a certain period time in case a connection to the same target host is needed for subsequent requests. The ability to keep connections alive is usually refered to as connection persistence. HttpClient fully supports connection persistence.
HTTP connection routing HttpClient is capable of establishing connections to the target host either directly or via a route that may involve multiple intermediate connections - also referred to as hops. HttpClient differentiates connections of a route into plain, tunneled and layered. The use of multiple intermediate proxies to tunnel connections to the target host is referred to as proxy chaining. Plain routes are established by connecting to the target or the first and only proxy. Tunnelled routes are established by connecting to the first and tunnelling through a chain of proxies to the target. Routes without a proxy cannot be tunnelled. Layered routes are established by layering a protocol over an existing connection. Protocols can only be layered over a tunnel to the target, or over a direct connection without proxies.
Route computation The RouteInfo interface represents information about a definitive route to a target host involving one or more intermediate steps or hops. HttpRoute is a concrete implementation of the RouteInfo, which cannot be changed (is immutable). HttpTracker is a mutable RouteInfo implementation used internally by HttpClient to track the remaining hops to the ultimate route target. HttpTracker can be updated after a successful execution of the next hop towards the route target. HttpRouteDirector is a helper class that can be used to compute the next step in a route. This class is used internally by HttpClient. HttpRoutePlanner is an interface representing a strategy to compute a complete route to a given target based on the execution context. HttpClient ships with two default HttpRoutePlanner implementations. SystemDefaultRoutePlanner is based on java.net.ProxySelector. By default, it will pick up the proxy settings of the JVM, either from system properties or from the browser running the application. The DefaultProxyRoutePlanner implementation does not make use of any Java system properties, nor any system or browser proxy settings. It always computes routes via the same default proxy.
Secure HTTP connections HTTP connections can be considered secure if information transmitted between two connection endpoints cannot be read or tampered with by an unauthorized third party. The SSL/TLS protocol is the most widely used technique to ensure HTTP transport security. However, other encryption techniques could be employed as well. Usually, HTTP transport is layered over the SSL/TLS encrypted connection.
HTTP connection managers
Managed connections and connection managers HTTP connections are complex, stateful, thread-unsafe objects which need to be properly managed to function correctly. HTTP connections can only be used by one execution thread at a time. HttpClient employs a special entity to manage access to HTTP connections called HTTP connection manager and represented by the HttpClientConnectionManager interface. The purpose of an HTTP connection manager is to serve as a factory for new HTTP connections, to manage life cycle of persistent connections and to synchronize access to persistent connections making sure that only one thread can have access to a connection at a time. Internally HTTP connection managers work with instances of ManagedHttpClientConnection acting as a proxy for a real connection that manages connection state and controls execution of I/O operations. If a managed connection is released or get explicitly closed by its consumer the underlying connection gets detached from its proxy and is returned back to the manager. Even though the service consumer still holds a reference to the proxy instance, it is no longer able to execute any I/O operations or change the state of the real connection either intentionally or unintentionally. This is an example of acquiring a connection from a connection manager: The connection request can be terminated prematurely by calling ConnectionRequest#cancel() if necessary. This will unblock the thread blocked in the ConnectionRequest#get() method.
Simple connection manager BasicHttpClientConnectionManager is a simple connection manager that maintains only one connection at a time. Even though this class is thread-safe it ought to be used by one execution thread only. BasicHttpClientConnectionManager will make an effort to reuse the connection for subsequent requests with the same route. It will, however, close the existing connection and re-open it for the given route, if the route of the persistent connection does not match that of the connection request. If the connection has been already been allocated, then java.lang.IllegalStateException is thrown. This connection manager implementation should be used inside an EJB container.
Pooling connection manager PoolingHttpClientConnectionManager is a more complex implementation that manages a pool of client connections and is able to service connection requests from multiple execution threads. Connections are pooled on a per route basis. A request for a route for which the manager already has a persistent connection available in the pool will be serviced by leasing a connection from the pool rather than creating a brand new connection. PoolingHttpClientConnectionManager maintains a maximum limit of connections on a per route basis and in total. Per default this implementation will create no more than 2 concurrent connections per given route and no more 20 connections in total. For many real-world applications these limits may prove too constraining, especially if they use HTTP as a transport protocol for their services. This example shows how the connection pool parameters can be adjusted:
Connection manager shutdown When an HttpClient instance is no longer needed and is about to go out of scope it is important to shut down its connection manager to ensure that all connections kept alive by the manager get closed and system resources allocated by those connections are released. httpClient.close(); ]]>
Multithreaded request execution When equipped with a pooling connection manager such as PoolingClientConnectionManager, HttpClient can be used to execute multiple requests simultaneously using multiple threads of execution. The PoolingClientConnectionManager will allocate connections based on its configuration. If all connections for a given route have already been leased, a request for a connection will block until a connection is released back to the pool. One can ensure the connection manager does not block indefinitely in the connection request operation by setting 'http.conn-manager.timeout' to a positive value. If the connection request cannot be serviced within the given time period ConnectionPoolTimeoutException will be thrown. While HttpClient instances are thread safe and can be shared between multiple threads of execution, it is highly recommended that each thread maintains its own dedicated instance of HttpContext .
Connection eviction policy One of the major shortcomings of the classic blocking I/O model is that the network socket can react to I/O events only when blocked in an I/O operation. When a connection is released back to the manager, it can be kept alive however it is unable to monitor the status of the socket and react to any I/O events. If the connection gets closed on the server side, the client side connection is unable to detect the change in the connection state (and react appropriately by closing the socket on its end). HttpClient tries to mitigate the problem by testing whether the connection is 'stale', that is no longer valid because it was closed on the server side, prior to using the connection for executing an HTTP request. The stale connection check is not 100% reliable and adds 10 to 30 ms overhead to each request execution. The only feasible solution that does not involve a one thread per socket model for idle connections is a dedicated monitor thread used to evict connections that are considered expired due to a long period of inactivity. The monitor thread can periodically call ClientConnectionManager#closeExpiredConnections() method to close all expired connections and evict closed connections from the pool. It can also optionally call ClientConnectionManager#closeIdleConnections() method to close all connections that have been idle over a given period of time.
Connection keep alive strategy The HTTP specification does not specify how long a persistent connection may be and should be kept alive. Some HTTP servers use a non-standard Keep-Alive header to communicate to the client the period of time in seconds they intend to keep the connection alive on the server side. HttpClient makes use of this information if available. If the Keep-Alive header is not present in the response, HttpClient assumes the connection can be kept alive indefinitely. However, many HTTP servers in general use are configured to drop persistent connections after a certain period of inactivity in order to conserve system resources, quite often without informing the client. In case the default strategy turns out to be too optimistic, one may want to provide a custom keep-alive strategy.
Connection socket factories HTTP connections make use of a java.net.Socket object internally to handle transmission of data across the wire. However they rely on the ConnectionSocketFactory interface to create, initialize and connect sockets. This enables the users of HttpClient to provide application specific socket initialization code at runtime. PlainConnectionSocketFactory is the default factory for creating and initializing plain (unencrypted) sockets. The process of creating a socket and that of connecting it to a host are decoupled, so that the socket could be closed while being blocked in the connect operation.
Secure socket layering LayeredConnectionSocketFactory is an extension of the ConnectionSocketFactory interface. Layered socket factories are capable of creating sockets layered over an existing plain socket. Socket layering is used primarily for creating secure sockets through proxies. HttpClient ships with SSLSocketFactory that implements SSL/TLS layering. Please note HttpClient does not use any custom encryption functionality. It is fully reliant on standard Java Cryptography (JCE) and Secure Sockets (JSEE) extensions.
Integration with connection manager Custom connection socket factories can be associated with a particular protocol scheme as as HTTP or HTTPS and then used to create a custom connection manager. LayeredConnectionSocketFactory sslsf = <...> Registry r = RegistryBuilder.create() .register("http", plainsf) .register("https", sslsf) .build(); HttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(r); HttpClients.custom() .setConnectionManager(cm) .build(); ]]>
SSL/TLS customization HttpClient makes use of SSLSocketFactory to create SSL connections. SSLSocketFactory allows for a high degree of customization. It can take an instance of javax.net.ssl.SSLContext as a parameter and use it to create custom configured SSL connections. SSLContext sslContext = SSLContexts.custom() .useTLS() .loadTrustMaterial(myTrustStore) .build(); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext); ]]> Customization of SSLSocketFactory implies a certain degree of familiarity with the concepts of the SSL/TLS protocol, a detailed explanation of which is out of scope for this document. Please refer to the Java Secure Socket Extension for a detailed description of javax.net.ssl.SSLContext and related tools.
Hostname verification In addition to the trust verification and the client authentication performed on the SSL/TLS protocol level, HttpClient can optionally verify whether the target hostname matches the names stored inside the server's X.509 certificate, once the connection has been established. This verification can provide additional guarantees of authenticity of the server trust material. The X509HostnameVerifier interface represents a strategy for hostname verification. HttpClient ships with three X509HostnameVerifier implementations. Important: hostname verification should not be confused with SSL trust verification. <classname>StrictHostnameVerifier</classname>: The strict hostname verifier works the same way as Sun Java 1.4, Sun Java 5, Sun Java 6. It's also pretty close to IE6. This implementation appears to be compliant with RFC 2818 for dealing with wildcards. The hostname must match either the first CN, or any of the subject-alts. A wildcard can occur in the CN, and in any of the subject-alts. <classname>BrowserCompatHostnameVerifier</classname>: This hostname verifier that works the same way as Curl and Firefox. The hostname must match either the first CN, or any of the subject-alts. A wildcard can occur in the CN, and in any of the subject-alts. The only difference between BrowserCompatHostnameVerifier and StrictHostnameVerifier is that a wildcard (such as "*.foo.com") with BrowserCompatHostnameVerifier matches all subdomains, including "a.b.foo.com". <classname>AllowAllHostnameVerifier</classname>: This hostname verifier essentially turns hostname verification off. This implementation is a no-op, and never throws javax.net.ssl.SSLException. Per default HttpClient uses the BrowserCompatHostnameVerifier implementation. One can specify a different hostname verifier implementation if desired
HttpClient proxy configuration Even though HttpClient is aware of complex routing scemes and proxy chaining, it supports only simple direct or one hop proxy connections out of the box. The simplest way to tell HttpClient to connect to the target host via a proxy is by setting the default proxy parameter: One can also instruct HttpClient to use the standard JRE proxy selector to obtain proxy information: Alternatively, one can provide a custom RoutePlanner implementation in order to have a complete control over the process of HTTP route computation:
httpcomponents-client-4.3.3/src/docbkx/fluent.xml0100644 0000000 0000000 00000013367 12301751746 020711 0ustar000000000 0000000 Fluent API
Easy to use facade API As of version of 4.2 HttpClient comes with an easy to use facade API based on the concept of a fluent interface. Fluent facade API exposes only the most fundamental functions of HttpClient and is intended for simple use cases that do not require the full flexibility of HttpClient. For instance, fluent facade API relieves the users from having to deal with connection management and resource deallocation. Here are several examples of HTTP requests executed through the HC fluent API One can also use Executor directly in order to execute requests in a specific security context whereby authentication details are cached and re-used for subsequent requests.
Response handling The fluent facade API generally relieves the users from having to deal with connection management and resource deallocation. In most cases, though, this comes at a price of having to buffer content of response messages in memory. It is highly recommended to use ResponseHandler for HTTP response processing in order to avoid having to buffer content in memory. () { public Document handleResponse(final HttpResponse response) throws IOException { StatusLine statusLine = response.getStatusLine(); HttpEntity entity = response.getEntity(); if (statusLine.getStatusCode() >= 300) { throw new HttpResponseException( statusLine.getStatusCode(), statusLine.getReasonPhrase()); } if (entity == null) { throw new ClientProtocolException("Response contains no content"); } DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); try { DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); ContentType contentType = ContentType.getOrDefault(entity); if (!contentType.equals(ContentType.APPLICATION_XML)) { throw new ClientProtocolException("Unexpected content type:" + contentType); } String charset = contentType.getCharset(); if (charset == null) { charset = HTTP.DEFAULT_CONTENT_CHARSET; } return docBuilder.parse(entity.getContent(), charset); } catch (ParserConfigurationException ex) { throw new IllegalStateException(ex); } catch (SAXException ex) { throw new ClientProtocolException("Malformed XML document", ex); } } }); ]]>
httpcomponents-client-4.3.3/src/docbkx/fundamentals.xml0100644 0000000 0000000 00000133117 12301751746 022071 0ustar000000000 0000000 Fundamentals
Request execution The most essential function of HttpClient is to execute HTTP methods. Execution of an HTTP method involves one or several HTTP request / HTTP response exchanges, usually handled internally by HttpClient. The user is expected to provide a request object to execute and HttpClient is expected to transmit the request to the target server return a corresponding response object, or throw an exception if execution was unsuccessful. Quite naturally, the main entry point of the HttpClient API is the HttpClient interface that defines the contract described above. Here is an example of request execution process in its simplest form: } finally { response.close(); } ]]>
HTTP request All HTTP requests have a request line consisting a method name, a request URI and an HTTP protocol version. HttpClient supports out of the box all HTTP methods defined in the HTTP/1.1 specification: GET, HEAD, POST, PUT, DELETE, TRACE and OPTIONS. There is a specific class for each method type.: HttpGet, HttpHead, HttpPost, HttpPut, HttpDelete, HttpTrace, and HttpOptions. The Request-URI is a Uniform Resource Identifier that identifies the resource upon which to apply the request. HTTP request URIs consist of a protocol scheme, host name, optional port, resource path, optional query, and optional fragment. HttpClient provides URIBuilder utility class to simplify creation and modification of request URIs. stdout >
HTTP response HTTP response is a message sent by the server back to the client after having received and interpreted a request message. The first line of that message consists of the protocol version followed by a numeric status code and its associated textual phrase. stdout >
Working with message headers An HTTP message can contain a number of headers describing properties of the message such as the content length, content type and so on. HttpClient provides methods to retrieve, add, remove and enumerate headers. stdout > The most efficient way to obtain all headers of a given type is by using the HeaderIterator interface. stdout > It also provides convenience methods to parse HTTP messages into individual header elements. stdout >
HTTP entity HTTP messages can carry a content entity associated with the request or response. Entities can be found in some requests and in some responses, as they are optional. Requests that use entities are referred to as entity enclosing requests. The HTTP specification defines two entity enclosing request methods: POST and PUT. Responses are usually expected to enclose a content entity. There are exceptions to this rule such as responses to HEAD method and 204 No Content, 304 Not Modified, 205 Reset Content responses. HttpClient distinguishes three kinds of entities, depending on where their content originates: streamed: The content is received from a stream, or generated on the fly. In particular, this category includes entities being received from HTTP responses. Streamed entities are generally not repeatable. self-contained: The content is in memory or obtained by means that are independent from a connection or other entity. Self-contained entities are generally repeatable. This type of entities will be mostly used for entity enclosing HTTP requests. wrapping: The content is obtained from another entity. This distinction is important for connection management when streaming out content from an HTTP response. For request entities that are created by an application and only sent using HttpClient, the difference between streamed and self-contained is of little importance. In that case, it is suggested to consider non-repeatable entities as streamed, and those that are repeatable as self-contained.
Repeatable entities An entity can be repeatable, meaning its content can be read more than once. This is only possible with self contained entities (like ByteArrayEntity or StringEntity)
Using HTTP entities Since an entity can represent both binary and character content, it has support for character encodings (to support the latter, ie. character content). The entity is created when executing a request with enclosed content or when the request was successful and the response body is used to send the result back to the client. To read the content from the entity, one can either retrieve the input stream via the HttpEntity#getContent() method, which returns an java.io.InputStream, or one can supply an output stream to the HttpEntity#writeTo(OutputStream) method, which will return once all content has been written to the given stream. When the entity has been received with an incoming message, the methods HttpEntity#getContentType() and HttpEntity#getContentLength() methods can be used for reading the common metadata such as Content-Type and Content-Length headers (if they are available). Since the Content-Type header can contain a character encoding for text mime-types like text/plain or text/html, the HttpEntity#getContentEncoding() method is used to read this information. If the headers aren't available, a length of -1 will be returned, and NULL for the content type. If the Content-Type header is available, a Header object will be returned. When creating an entity for a outgoing message, this meta data has to be supplied by the creator of the entity. stdout >
Ensuring release of low level resources In order to ensure proper release of system resources one must close either the content stream associated with the entity or the response itself The difference between closing the content stream and closing the response is that the former will attempt to keep the underlying connection alive by consuming the entity content while the latter immediately shuts down and discards the connection. Please note that the HttpEntity#writeTo(OutputStream) method is also required to ensure proper release of system resources once the entity has been fully written out. If this method obtains an instance of java.io.InputStream by calling HttpEntity#getContent(), it is also expected to close the stream in a finally clause. When working with streaming entities, one can use the EntityUtils#consume(HttpEntity) method to ensure that the entity content has been fully consumed and the underlying stream has been closed. There can be situations, however, when only a small portion of the entire response content needs to be retrieved and the performance penalty for consuming the remaining content and making the connection reusable is too high, in which case one can terminate the content stream by closing the response. The connection will not be reused, but all level resources held by it will be correctly deallocated.
Consuming entity content The recommended way to consume the content of an entity is by using its HttpEntity#getContent() or HttpEntity#writeTo(OutputStream) methods. HttpClient also comes with the EntityUtils class, which exposes several static methods to more easily read the content or information from an entity. Instead of reading the java.io.InputStream directly, one can retrieve the whole content body in a string / byte array by using the methods from this class. However, the use of EntityUtils is strongly discouraged unless the response entities originate from a trusted HTTP server and are known to be of limited length. In some situations it may be necessary to be able to read entity content more than once. In this case entity content must be buffered in some way, either in memory or on disk. The simplest way to accomplish that is by wrapping the original entity with the BufferedHttpEntity class. This will cause the content of the original entity to be read into a in-memory buffer. In all other ways the entity wrapper will be have the original one. HttpEntity entity = response.getEntity(); if (entity != null) { entity = new BufferedHttpEntity(entity); } ]]>
Producing entity content HttpClient provides several classes that can be used to efficiently stream out content throught HTTP connections. Instances of those classes can be associated with entity enclosing requests such as POST and PUT in order to enclose entity content into outgoing HTTP requests. HttpClient provides several classes for most common data containers such as string, byte array, input stream, and file: StringEntity, ByteArrayEntity, InputStreamEntity, and FileEntity. Please note InputStreamEntity is not repeatable, because it can only read from the underlying data stream once. Generally it is recommended to implement a custom HttpEntity class which is self-contained instead of using the generic InputStreamEntity. FileEntity can be a good starting point.
HTML forms Many applications need to simulate the process of submitting an HTML form, for instance, in order to log in to a web application or submit input data. HttpClient provides the entity class UrlEncodedFormEntity to facilitate the process. formparams = new ArrayList(); formparams.add(new BasicNameValuePair("param1", "value1")); formparams.add(new BasicNameValuePair("param2", "value2")); UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8); HttpPost httppost = new HttpPost("http://localhost/handler.do"); httppost.setEntity(entity); ]]> The UrlEncodedFormEntity instance will use the so called URL encoding to encode parameters and produce the following content:
Content chunking Generally it is recommended to let HttpClient choose the most appropriate transfer encoding based on the properties of the HTTP message being transferred. It is possible, however, to inform HttpClient that chunk coding is preferred by setting HttpEntity#setChunked() to true. Please note that HttpClient will use this flag as a hint only. This value will be ignored when using HTTP protocol versions that do not support chunk coding, such as HTTP/1.0.
Response handlers The simplest and the most convenient way to handle responses is by using the ResponseHandler interface, which includes the handleResponse(HttpResponse response) method. This method completely relieves the user from having to worry about connection management. When using a ResponseHandler, HttpClient will automatically take care of ensuring release of the connection back to the connection manager regardless whether the request execution succeeds or causes an exception. rh = new ResponseHandler() { @Override public JsonObject handleResponse( final HttpResponse response) throws IOException { StatusLine statusLine = response.getStatusLine(); HttpEntity entity = response.getEntity(); if (statusLine.getStatusCode() >= 300) { throw new HttpResponseException( statusLine.getStatusCode(), statusLine.getReasonPhrase()); } if (entity == null) { throw new ClientProtocolException("Response contains no content"); } Gson gson = new GsonBuilder().create(); ContentType contentType = ContentType.getOrDefault(entity); Charset charset = contentType.getCharset(); Reader reader = new InputStreamReader(entity.getContent(), charset); return gson.fromJson(reader, MyJsonObject.class); } }; MyJsonObject myjson = client.execute(httpget, rh); ]]>
HttpClient interface HttpClient interface represents the most essential contract for HTTP request execution. It imposes no restrictions or particular details on the request execution process and leaves the specifics of connection management, state management, authentication and redirect handling up to individual implementations. This should make it easier to decorate the interface with additional functionality such as response content caching. Generally HttpClient implementations act as a facade to a number of special purpose handler or strategy interface implementations responsible for handling of a particular aspect of the HTTP protocol such as redirect or authentication handling or making decision about connection persistence and keep alive duration. This enables the users to selectively replace default implementation of those aspects with custom, application specific ones.
HttpClient thread safety HttpClient implementations are expected to be thread safe. It is recommended that the same instance of this class is reused for multiple request executions.
HttpClient resource deallocation When an instance CloseableHttpClient is no longer needed and is about to go out of scope the connection manager associated with it must be shut down by calling the CloseableHttpClient#close() method. } finally { httpclient.close(); } ]]>
HTTP execution context Originally HTTP has been designed as a stateless, response-request oriented protocol. However, real world applications often need to be able to persist state information through several logically related request-response exchanges. In order to enable applications to maintain a processing state HttpClient allows HTTP requests to be executed within a particular execution context, referred to as HTTP context. Multiple logically related requests can participate in a logical session if the same context is reused between consecutive requests. HTTP context functions similarly to a java.util.Map<String, Object>. It is simply a collection of arbitrary named values. An application can populate context attributes prior to request execution or examine the context after the execution has been completed. HttpContext can contain arbitrary objects and therefore may be unsafe to share between multiple threads. It is recommended that each thread of execution maintains its own context. In the course of HTTP request execution HttpClient adds the following attributes to the execution context: HttpConnection instance representing the actual connection to the target server. HttpHost instance representing the connection target. HttpRoute instance representing the complete connection route HttpRequest instance representing the actual HTTP request. The final HttpRequest object in the execution context always represents the state of the message exactly as it was sent to the target server. Per default HTTP/1.0 and HTTP/1.1 use relative request URIs. However if the request is sent via a proxy in a non-tunneling mode then the URI will be absolute. HttpResponse instance representing the actual HTTP response. java.lang.Boolean object representing the flag indicating whether the actual request has been fully transmitted to the connection target. RequestConfig object representing the actual request configuation. java.util.List<URI> object representing a collection of all redirect locations received in the process of request execution. One can use HttpClientContext adaptor class to simplify interractions with the context state. HttpClientContext clientContext = HttpClientContext.adapt(context); HttpHost target = clientContext.getTargetHost(); HttpRequest request = clientContext.getRequest(); HttpResponse response = clientContext.getResponse(); RequestConfig config = clientContext.getRequestConfig(); ]]> Multiple request sequences that represent a logically related session should be executed with the same HttpContext instance to ensure automatic propagation of conversation context and state information between requests. In the following example the request configuration set by the initial request will be kept in the execution context and get propagated to the consecutive requests sharing the same context.
Exception handling HttpClient can throw two types of exceptions: java.io.IOException in case of an I/O failure such as socket timeout or an socket reset and HttpException that signals an HTTP failure such as a violation of the HTTP protocol. Usually I/O errors are considered non-fatal and recoverable, whereas HTTP protocol errors are considered fatal and cannot be automatically recovered from.
HTTP transport safety It is important to understand that the HTTP protocol is not well suited to all types of applications. HTTP is a simple request/response oriented protocol which was initially designed to support static or dynamically generated content retrieval. It has never been intended to support transactional operations. For instance, the HTTP server will consider its part of the contract fulfilled if it succeeds in receiving and processing the request, generating a response and sending a status code back to the client. The server will make no attempt to roll back the transaction if the client fails to receive the response in its entirety due to a read timeout, a request cancellation or a system crash. If the client decides to retry the same request, the server will inevitably end up executing the same transaction more than once. In some cases this may lead to application data corruption or inconsistent application state. Even though HTTP has never been designed to support transactional processing, it can still be used as a transport protocol for mission critical applications provided certain conditions are met. To ensure HTTP transport layer safety the system must ensure the idempotency of HTTP methods on the application layer.
Idempotent methods HTTP/1.1 specification defines an idempotent method as Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request In other words the application ought to ensure that it is prepared to deal with the implications of multiple execution of the same method. This can be achieved, for instance, by providing a unique transaction id and by other means of avoiding execution of the same logical operation. Please note that this problem is not specific to HttpClient. Browser based applications are subject to exactly the same issues related to HTTP methods non-idempotency. HttpClient assumes non-entity enclosing methods such as GET and HEAD to be idempotent and entity enclosing methods such as POST and PUT to be not.
Automatic exception recovery By default HttpClient attempts to automatically recover from I/O exceptions. The default auto-recovery mechanism is limited to just a few exceptions that are known to be safe. HttpClient will make no attempt to recover from any logical or HTTP protocol errors (those derived from HttpException class). HttpClient will automatically retry those methods that are assumed to be idempotent. HttpClient will automatically retry those methods that fail with a transport exception while the HTTP request is still being transmitted to the target server (i.e. the request has not been fully transmitted to the server).
Request retry handler In order to enable a custom exception recovery mechanism one should provide an implementation of the HttpRequestRetryHandler interface. = 5) { // Do not retry if over max retry count return false; } if (exception instanceof InterruptedIOException) { // Timeout return false; } if (exception instanceof UnknownHostException) { // Unknown host return false; } if (exception instanceof ConnectTimeoutException) { // Connection refused return false; } if (exception instanceof SSLException) { // SSL handshake exception return false; } HttpClientContext clientContext = HttpClientContext.adapt(context); HttpRequest request = clientContext.getRequest(); boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); if (idempotent) { // Retry if the request is considered idempotent return true; } return false; } }; CloseableHttpClient httpclient = HttpClients.custom() .setRetryHandler(myRetryHandler) .build(); ]]>
Aborting requests In some situations HTTP request execution fails to complete within the expected time frame due to high load on the target server or too many concurrent requests issued on the client side. In such cases it may be necessary to terminate the request prematurely and unblock the execution thread blocked in a I/O operation. HTTP requests being executed by HttpClient can be aborted at any stage of execution by invoking HttpUriRequest#abort() method. This method is thread-safe and can be called from any thread. When an HTTP request is aborted its execution thread - even if currently blocked in an I/O operation - is guaranteed to unblock by throwing a InterruptedIOException
HTTP protocol interceptors The HTTP protocol interceptor is a routine that implements a specific aspect of the HTTP protocol. Usually protocol interceptors are expected to act upon one specific header or a group of related headers of the incoming message, or populate the outgoing message with one specific header or a group of related headers. Protocol interceptors can also manipulate content entities enclosed with messages - transparent content compression / decompression being a good example. Usually this is accomplished by using the 'Decorator' pattern where a wrapper entity class is used to decorate the original entity. Several protocol interceptors can be combined to form one logical unit. Protocol interceptors can collaborate by sharing information - such as a processing state - through the HTTP execution context. Protocol interceptors can use HTTP context to store a processing state for one request or several consecutive requests. Usually the order in which interceptors are executed should not matter as long as they do not depend on a particular state of the execution context. If protocol interceptors have interdependencies and therefore must be executed in a particular order, they should be added to the protocol processor in the same sequence as their expected execution order. Protocol interceptors must be implemented as thread-safe. Similarly to servlets, protocol interceptors should not use instance variables unless access to those variables is synchronized. This is an example of how local context can be used to persist a processing state between consecutive requests:
Redirect handling HttpClient handles all types of redirects automatically, except those explicitly prohibited by the HTTP specification as requiring user intervention. See Other (status code 303) redirects on POST and PUT requests are converted to GET requests as required by the HTTP specification. One can use a custom redirect strategy to relaxe restrictions on automatic redirection of POST methods imposed by the HTTP specification. HttpClient often has to rewrite the request message in the process of its execution. Per default HTTP/1.0 and HTTP/1.1 generally use relative request URIs. Likewise, original request may get redirected from location to another multiple times. The final interpreted absolute HTTP location can be built using the original request and the context. The utility method URIUtils#resolve can be used to build the interpreted absolute URI used to generate the final request. This method includes the last fragment identifier from the redirect requests or the original request. redirectLocations = context.getRedirectLocations(); URI location = URIUtils.resolve(httpget.getURI(), target, redirectLocations); System.out.println("Final HTTP location: " + location.toASCIIString()); // Expected to be an absolute URI } finally { response.close(); } ]]>
httpcomponents-client-4.3.3/src/docbkx/index.xml0100644 0000000 0000000 00000006224 12301751744 020513 0ustar000000000 0000000 HttpClient Tutorial &version; Oleg Kalnichevski Jonathan Moore Jilles van Gurp 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 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. httpcomponents-client-4.3.3/src/docbkx/preface.xml0100644 0000000 0000000 00000007061 12301751746 021013 0ustar000000000 0000000 Preface The Hyper-Text Transfer Protocol (HTTP) is perhaps the most significant protocol used on the Internet today. Web services, network-enabled appliances and the growth of network computing continue to expand the role of the HTTP protocol beyond user-driven web browsers, while increasing the number of applications that require HTTP support. Although the java.net package provides basic functionality for accessing resources via HTTP, it doesn't provide the full flexibility or functionality needed by many applications. HttpClient seeks to fill this void by providing an efficient, up-to-date, and feature-rich package implementing the client side of the most recent HTTP standards and recommendations. Designed for extension while providing robust support for the base HTTP protocol, HttpClient may be of interest to anyone building HTTP-aware client applications such as web browsers, web service clients, or systems that leverage or extend the HTTP protocol for distributed communication.
HttpClient scope Client-side HTTP transport library based on HttpCore Based on classic (blocking) I/O Content agnostic
What HttpClient is NOT HttpClient is NOT a browser. It is a client side HTTP transport library. HttpClient's purpose is to transmit and receive HTTP messages. HttpClient will not attempt to process content, execute javascript embedded in HTML pages, try to guess content type, if not explicitly set, or reformat request / redirect location URIs, or other functionality unrelated to the HTTP transport.
httpcomponents-client-4.3.3/src/docbkx/statemgmt.xml0100644 0000000 0000000 00000036546 12301751746 021425 0ustar000000000 0000000 HTTP state management Originally HTTP was designed as a stateless, request / response oriented protocol that made no special provisions for stateful sessions spanning across several logically related request / response exchanges. As HTTP protocol grew in popularity and adoption more and more systems began to use it for applications it was never intended for, for instance as a transport for e-commerce applications. Thus, the support for state management became a necessity. Netscape Communications, at that time a leading developer of web client and server software, implemented support for HTTP state management in their products based on a proprietary specification. Later, Netscape tried to standardise the mechanism by publishing a specification draft. Those efforts contributed to the formal specification defined through the RFC standard track. However, state management in a significant number of applications is still largely based on the Netscape draft and is incompatible with the official specification. All major developers of web browsers felt compelled to retain compatibility with those applications greatly contributing to the fragmentation of standards compliance.
HTTP cookies An HTTP cookie is a token or short packet of state information that the HTTP agent and the target server can exchange to maintain a session. Netscape engineers used to refer to it as a "magic cookie" and the name stuck. HttpClient uses the Cookie interface to represent an abstract cookie token. In its simplest form an HTTP cookie is merely a name / value pair. Usually an HTTP cookie also contains a number of attributes such as version, a domain for which is valid, a path that specifies the subset of URLs on the origin server to which this cookie applies, and the maximum period of time for which the cookie is valid. The SetCookie interface represents a Set-Cookie response header sent by the origin server to the HTTP agent in order to maintain a conversational state. The SetCookie2 interface extends SetCookie with Set-Cookie2 specific methods. The ClientCookie interface extends Cookie interface with additional client specific functionality such as the ability to retrieve original cookie attributes exactly as they were specified by the origin server. This is important for generating the Cookie header because some cookie specifications require that the Cookie header should include certain attributes only if they were specified in the Set-Cookie or Set-Cookie2 header.
Cookie versions Cookies compatible with Netscape draft specification but non-compliant with the official specification are considered to be of version 0. Standard compliant cookies are expected to have version 1. HttpClient may handle cookies differently depending on the version. Here is an example of re-creating a Netscape cookie: Here is an example of re-creating a standard cookie. Please note that standard compliant cookie must retain all attributes as sent by the origin server: Here is an example of re-creating a Set-Cookie2 compliant cookie. Please note that standard compliant cookie must retain all attributes as sent by the origin server:
Cookie specifications The CookieSpec interface represents a cookie management specification. The cookie management specification is expected to enforce: rules of parsing Set-Cookie and optionally Set-Cookie2 headers. rules of validation of parsed cookies. formatting of Cookie header for a given host, port and path of origin. HttpClient ships with several CookieSpec implementations: Netscape draft: This specification conforms to the original draft specification published by Netscape Communications. It should be avoided unless absolutely necessary for compatibility with legacy code. Standard: RFC 2965 HTTP state management specification. Browser compatibility: This implementation strives to closely mimic the (mis)behavior of common web browser applications such as Microsoft Internet Explorer and Mozilla FireFox. Best match: 'Meta' cookie specification that picks up a cookie policy based on the format of cookies sent with the HTTP response. It basically aggregates all above implementations into one class. Ignore cookies: All cookies are ignored. It is strongly recommended to use the Best Match policy and let HttpClient pick up an appropriate compliance level at runtime based on the execution context.
Choosing cookie policy Cookie policy can be set at the HTTP client and overridden on the HTTP request level if required.
Custom cookie policy In order to implement a custom cookie policy one should create a custom implementation of the CookieSpec interface, create a CookieSpecProvider implementation to create and initialize instances of the custom specification and register the factory with HttpClient. Once the custom specification has been registered, it can be activated the same way as a standard cookie specification. r = RegistryBuilder.create() .register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory()) .register(CookieSpecs.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory()) .register("easy", easySpecProvider) .build(); RequestConfig requestConfig = RequestConfig.custom() .setCookieSpec("easy") .build(); CloseableHttpClient httpclient = HttpClients.custom() .setDefaultCookieSpecRegistry(r) .setDefaultRequestConfig(requestConfig) .build(); ]]>
Cookie persistence HttpClient can work with any physical representation of a persistent cookie store that implements the CookieStore interface. The default CookieStore implementation called BasicCookieStore is a simple implementation backed by a java.util.ArrayList. Cookies stored in an BasicClientCookie object are lost when the container object get garbage collected. Users can provide more complex implementations if necessary.
HTTP state management and execution context In the course of HTTP request execution HttpClient adds the following state management related objects to the execution context: Lookup instance representing the actual cookie specification registry. The value of this attribute set in the local context takes precedence over the default one. CookieSpec instance representing the actual cookie specification. CookieOrigin instance representing the actual details of the origin server. CookieStore instance representing the actual cookie store. The value of this attribute set in the local context takes precedence over the default one. The local HttpContext object can be used to customize the HTTP state management context prior to request execution, or to examine its state after the request has been executed. One can also use separate execution contexts in order to implement per user (or per thread) state management. A cookie specification registry and cookie store defined in the local context will take precedence over the default ones set at the HTTP client level Lookup cookieSpecReg = <...> CookieStore cookieStore = <...> HttpClientContext context = HttpClientContext.create(); context.setCookieSpecRegistry(cookieSpecReg); context.setCookieStore(cookieStore); HttpGet httpget = new HttpGet("http://somehost/"); CloseableHttpResponse response1 = httpclient.execute(httpget, context); <...> // Cookie origin details CookieOrigin cookieOrigin = context.getCookieOrigin(); // Cookie spec used CookieSpec cookieSpec = context.getCookieSpec(); ]]>
httpcomponents-client-4.3.3/src/docbkx/resources/0040755 0000000 0000000 00000000000 12301751745 020674 5ustar000000000 0000000 httpcomponents-client-4.3.3/src/docbkx/resources/css/0040755 0000000 0000000 00000000000 12301751745 021464 5ustar000000000 0000000 httpcomponents-client-4.3.3/src/docbkx/resources/css/hc-tutorial.css0100644 0000000 0000000 00000012231 12301751745 024425 0ustar000000000 0000000 /* ==================================================================== 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. ==================================================================== This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation. For more information on the Apache Software Foundation, please see . ==================================================================== Based on the CSS file for the Spring Reference Documentation. */ body { text-align: justify; margin-right: 2em; margin-left: 2em; } a:active { color: #003399; } a:visited { color: #888888; } p { font-family: Verdana, Arial, sans-serif; } dt { font-family: Verdana, Arial, sans-serif; font-size: 12px; } p, dl, dt, dd, blockquote { color: #000000; margin-bottom: 3px; margin-top: 3px; padding-top: 0px; } ol, ul, p { margin-top: 6px; margin-bottom: 6px; } p, blockquote { font-size: 90%; } p.releaseinfo { font-size: 100%; font-weight: bold; font-family: Verdana, Arial, helvetica, sans-serif; padding-top: 10px; } p.pubdate { font-size: 120%; font-weight: bold; font-family: Verdana, Arial, helvetica, sans-serif; } td { font-size: 80%; } td, th, span { color: #000000; } blockquote { margin-right: 0px; } h1, h2, h3, h4, h6, H6 { color: #000000; font-weight: 500; margin-top: 0px; padding-top: 14px; font-family: Verdana, Arial, helvetica, sans-serif; margin-bottom: 0px; } h2.title { font-weight: 800; margin-bottom: 8px; } h2.subtitle { font-weight: 800; margin-bottom: 20px; } .firstname, .surname { font-size: 12px; font-family: Verdana, Arial, helvetica, sans-serif; } table { border-collapse: collapse; border-spacing: 0; border: 1px black; empty-cells: hide; margin: 10px 0px 30px 50px; width: 90%; } div.table { margin: 30px 0px 30px 0px; border: 1px dashed gray; padding: 10px; } div .table-contents table { border: 1px solid black; } div.table > p.title { padding-left: 10px; } td { padding: 4pt; font-family: Verdana, Arial, helvetica, sans-serif; } div.warning TD { text-align: justify; } h1 { font-size: 150%; } h2 { font-size: 110%; } h3 { font-size: 100%; font-weight: bold; } h4 { font-size: 90%; font-weight: bold; } h5 { font-size: 90%; font-style: italic; } h6 { font-size: 100%; font-style: italic; } tt { font-size: 110%; font-family: "Courier New", Courier, monospace; color: #000000; } .navheader, .navfooter { border: none; } pre { font-size: 110%; padding: 5px; border-style: solid; border-width: 1px; border-color: #CCCCCC; background-color: #f3f5e9; } ul, ol, li { list-style: disc; } hr { width: 100%; height: 1px; background-color: #CCCCCC; border-width: 0px; padding: 0px; } .variablelist { padding-top: 10px; padding-bottom: 10px; margin: 0; } .term { font-weight: bold; } .mediaobject { padding-top: 30px; padding-bottom: 30px; } .legalnotice { font-family: Verdana, Arial, helvetica, sans-serif; font-size: 12px; font-style: italic; } .sidebar { float: right; margin: 10px 0px 10px 30px; padding: 10px 20px 20px 20px; width: 33%; border: 1px solid black; background-color: #F4F4F4; font-size: 14px; } .property { font-family: "Courier New", Courier, monospace; } a code { font-family: Verdana, Arial, monospace; font-size: 12px; } td code { font-size: 110%; } div.note * td, div.tip * td, div.warning * td, div.calloutlist * td { text-align: justify; font-size: 100%; } .programlisting .interfacename, .programlisting .literal, .programlisting .classname { font-size: 95%; } .title .interfacename, .title .literal, .title .classname { font-size: 130%; } .programlisting * .lineannotation, .programlisting * .lineannotation * { color: blue; } .bannerLeft, .bannerRight { font-size: xx-large; font-weight: bold; } .bannerLeft img, .bannerRight img { margin: 0px; } .bannerLeft img { float:left; text-shadow: #7CFC00; } .bannerRight img { float:right; text-shadow: #7CFC00; } .banner { padding: 0px; } .banner img { border: none; } .clear { clear:both; visibility: hidden; }httpcomponents-client-4.3.3/src/docbkx/resources/images/0040755 0000000 0000000 00000000000 12301751745 022141 5ustar000000000 0000000 httpcomponents-client-4.3.3/src/docbkx/resources/images/SPNEGO.svg0100644 0000000 0000000 00000210355 12301751745 023660 0ustar000000000 0000000 GET /secure HTTP/1.1HTTP 401WWW-Authenticate: NegotiateGET /secure HTTP/1.1Authorization: Negotiate YIIGSg....1.2.HTTP 200Authorization: Negotiate YIIXXX....3.4a.5.Possible Further Neotiation (bidirectional)Authorization: Negotiate YIIXXX...UserWeb Server httpcomponents-client-4.3.3/src/docbkx/resources/xsl/0040755 0000000 0000000 00000000000 12301751745 021502 5ustar000000000 0000000 httpcomponents-client-4.3.3/src/docbkx/resources/xsl/fopdf.xsl0100644 0000000 0000000 00000040336 12301751745 023333 0ustar000000000 0000000 -5em -5em HttpClient ( ) book toc 2 1 0 0 0 5mm 10mm 10mm 15mm 10mm 0mm 18mm 18mm 0pc justify false 11 8 1.4 0.8em 17.4cm 4pt 4pt 4pt 4pt 0.1pt 0.1pt 1 left bold pt 0.8em 0.8em 0.8em pt 0.1em 0.1em 0.1em 0.6em 0.6em 0.6em pt 0.1em 0.1em 0.1em 0.4em 0.4em 0.4em pt 0.1em 0.1em 0.1em bold pt false 0.4em 0.6em 0.8em pt 1em 1em 1em #444444 solid 0.1pt 0.5em 0.5em 0.5em 0.5em 0.5em 0.5em 1 #F0F0F0 0 1 90 '1' figure after example before equation before table before procedure before 1 0.8em 0.8em 0.8em 0.1em 0.1em 0.1em httpcomponents-client-4.3.3/src/docbkx/resources/xsl/html.xsl0100644 0000000 0000000 00000010770 12301751745 023200 0ustar000000000 0000000 html.css 1 0 1 0 book toc 3 1 0 90 0 figure after example before equation before table before procedure before ,

Authors

httpcomponents-client-4.3.3/src/docbkx/resources/xsl/html_chunk.xsl0100644 0000000 0000000 00000011733 12301751745 024370 0ustar000000000 0000000 '5' '1' 1 0 1 0 book toc 3 1 1 90 figure after example before equation before table before procedure before ,

Authors