mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 05:40:42 +00:00 
			
		
		
		
	bump(github.com/coreos/go-oidc): 065b426bd41667456c1a924468f507673629c46b
This commit is contained in:
		
							
								
								
									
										10
									
								
								vendor/github.com/pquerna/cachecontrol/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/pquerna/cachecontrol/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| language: go | ||||
|  | ||||
| install: | ||||
|   - go get -d -v ./... | ||||
|   - go get -u github.com/stretchr/testify/require | ||||
|  | ||||
| go: | ||||
|   - 1.7 | ||||
|   - 1.8 | ||||
|   - tip | ||||
							
								
								
									
										29
									
								
								vendor/github.com/pquerna/cachecontrol/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/pquerna/cachecontrol/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| load("@io_bazel_rules_go//go:def.bzl", "go_library") | ||||
|  | ||||
| go_library( | ||||
|     name = "go_default_library", | ||||
|     srcs = [ | ||||
|         "api.go", | ||||
|         "doc.go", | ||||
|     ], | ||||
|     importpath = "github.com/pquerna/cachecontrol", | ||||
|     visibility = ["//visibility:public"], | ||||
|     deps = ["//vendor/github.com/pquerna/cachecontrol/cacheobject:go_default_library"], | ||||
| ) | ||||
|  | ||||
| filegroup( | ||||
|     name = "package-srcs", | ||||
|     srcs = glob(["**"]), | ||||
|     tags = ["automanaged"], | ||||
|     visibility = ["//visibility:private"], | ||||
| ) | ||||
|  | ||||
| filegroup( | ||||
|     name = "all-srcs", | ||||
|     srcs = [ | ||||
|         ":package-srcs", | ||||
|         "//vendor/github.com/pquerna/cachecontrol/cacheobject:all-srcs", | ||||
|     ], | ||||
|     tags = ["automanaged"], | ||||
|     visibility = ["//visibility:public"], | ||||
| ) | ||||
							
								
								
									
										202
									
								
								vendor/github.com/pquerna/cachecontrol/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								vendor/github.com/pquerna/cachecontrol/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,202 @@ | ||||
|  | ||||
|                                  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 | ||||
|  | ||||
|    APPENDIX: How to apply the Apache License to your work. | ||||
|  | ||||
|       To apply the Apache License to your work, attach the following | ||||
|       boilerplate notice, with the fields enclosed by brackets "[]" | ||||
|       replaced with your own identifying information. (Don't include | ||||
|       the brackets!)  The text should be enclosed in the appropriate | ||||
|       comment syntax for the file format. We also recommend that a | ||||
|       file or class name and description of purpose be included on the | ||||
|       same "printed page" as the copyright notice for easier | ||||
|       identification within third-party archives. | ||||
|  | ||||
|    Copyright [yyyy] [name of copyright owner] | ||||
|  | ||||
|    Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|    you may not use this file except in compliance with the License. | ||||
|    You may obtain a copy of the License at | ||||
|  | ||||
|        http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
|    Unless required by applicable law or agreed to in writing, software | ||||
|    distributed under the License is distributed on an "AS IS" BASIS, | ||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|    See the License for the specific language governing permissions and | ||||
|    limitations under the License. | ||||
							
								
								
									
										107
									
								
								vendor/github.com/pquerna/cachecontrol/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								vendor/github.com/pquerna/cachecontrol/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | ||||
| # cachecontrol: HTTP Caching Parser and Interpretation | ||||
|  | ||||
| [](https://godoc.org/github.com/pquerna/cachecontrol)[](https://travis-ci.org/pquerna/cachecontrol) | ||||
|  | ||||
|   | ||||
|  | ||||
| `cachecontrol` implements [RFC 7234](http://tools.ietf.org/html/rfc7234) __Hypertext Transfer Protocol (HTTP/1.1): Caching__.  It does this by parsing the `Cache-Control` and other headers, providing information about requests and responses -- but `cachecontrol` does not implement an actual cache backend, just the control plane to make decisions about if a particular response is cachable. | ||||
|  | ||||
| # Usage | ||||
|  | ||||
| `cachecontrol.CachableResponse` returns an array of [reasons](https://godoc.org/github.com/pquerna/cachecontrol/cacheobject#Reason) why a response should not be cached and when it expires.  In the case that `len(reasons) == 0`, the response is cachable according to the RFC.  However, some people want non-compliant caches for various business use cases, so each reason is specifically named, so if your cache wants to cache `POST` requests, it can easily do that, but still be RFC compliant in other situations. | ||||
|  | ||||
| # Examples | ||||
|  | ||||
| ## Can you cache Example.com? | ||||
|  | ||||
| ```go | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"github.com/pquerna/cachecontrol" | ||||
|  | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	req, _ := http.NewRequest("GET", "http://www.example.com/", nil) | ||||
|  | ||||
| 	res, _ := http.DefaultClient.Do(req) | ||||
| 	_, _ = ioutil.ReadAll(res.Body) | ||||
|  | ||||
| 	reasons, expires, _ := cachecontrol.CachableResponse(req, res, cachecontrol.Options{}) | ||||
|  | ||||
| 	fmt.Println("Reasons to not cache: ", reasons) | ||||
| 	fmt.Println("Expiration: ", expires.String()) | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ## Can I use this in a high performance caching server? | ||||
|  | ||||
| `cachecontrol` is divided into two packages: `cachecontrol` with a high level API, and a lower level `cacheobject` package.  Use [Object](https://godoc.org/github.com/pquerna/cachecontrol/cacheobject#Object) in a high performance use case where you have previously parsed headers containing dates or would like to avoid memory allocations. | ||||
|  | ||||
| ```go | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"github.com/pquerna/cachecontrol/cacheobject" | ||||
|  | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	req, _ := http.NewRequest("GET", "http://www.example.com/", nil) | ||||
|  | ||||
| 	res, _ := http.DefaultClient.Do(req) | ||||
| 	_, _ = ioutil.ReadAll(res.Body) | ||||
|  | ||||
| 	reqDir, _ := cacheobject.ParseRequestCacheControl(req.Header.Get("Cache-Control")) | ||||
|  | ||||
| 	resDir, _ := cacheobject.ParseResponseCacheControl(res.Header.Get("Cache-Control")) | ||||
| 	expiresHeader, _ := http.ParseTime(res.Header.Get("Expires")) | ||||
| 	dateHeader, _ := http.ParseTime(res.Header.Get("Date")) | ||||
| 	lastModifiedHeader, _ := http.ParseTime(res.Header.Get("Last-Modified")) | ||||
|  | ||||
| 	obj := cacheobject.Object{ | ||||
| 		RespDirectives:         resDir, | ||||
| 		RespHeaders:            res.Header, | ||||
| 		RespStatusCode:         res.StatusCode, | ||||
| 		RespExpiresHeader:      expiresHeader, | ||||
| 		RespDateHeader:         dateHeader, | ||||
| 		RespLastModifiedHeader: lastModifiedHeader, | ||||
|  | ||||
| 		ReqDirectives: reqDir, | ||||
| 		ReqHeaders:    req.Header, | ||||
| 		ReqMethod:     req.Method, | ||||
|  | ||||
| 		NowUTC: time.Now().UTC(), | ||||
| 	} | ||||
| 	rv := cacheobject.ObjectResults{} | ||||
|  | ||||
| 	cacheobject.CachableObject(&obj, &rv) | ||||
| 	cacheobject.ExpirationObject(&obj, &rv) | ||||
|  | ||||
| 	fmt.Println("Errors: ", rv.OutErr) | ||||
| 	fmt.Println("Reasons to not cache: ", rv.OutReasons) | ||||
| 	fmt.Println("Warning headers to add: ", rv.OutWarnings) | ||||
| 	fmt.Println("Expiration: ", rv.OutExpirationTime.String()) | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ## Improvements, bugs, adding features, and taking cachecontrol new directions! | ||||
|  | ||||
| Please [open issues in Github](https://github.com/pquerna/cachecontrol/issues) for ideas, bugs, and general thoughts.  Pull requests are of course preferred :) | ||||
|  | ||||
| # Credits | ||||
|  | ||||
| `cachecontrol` has recieved significant contributions from: | ||||
|  | ||||
| * [Paul Querna](https://github.com/pquerna)  | ||||
|  | ||||
| ## License | ||||
|  | ||||
| `cachecontrol` is licensed under the [Apache License, Version 2.0](./LICENSE) | ||||
							
								
								
									
										48
									
								
								vendor/github.com/pquerna/cachecontrol/api.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vendor/github.com/pquerna/cachecontrol/api.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| /** | ||||
|  *  Copyright 2015 Paul Querna | ||||
|  * | ||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  *  you may not use this file except in compliance with the License. | ||||
|  *  You may obtain a copy of the License at | ||||
|  * | ||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  *  Unless required by applicable law or agreed to in writing, software | ||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  *  See the License for the specific language governing permissions and | ||||
|  *  limitations under the License. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| package cachecontrol | ||||
|  | ||||
| import ( | ||||
| 	"github.com/pquerna/cachecontrol/cacheobject" | ||||
|  | ||||
| 	"net/http" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| type Options struct { | ||||
| 	// Set to True for a prviate cache, which is not shared amoung users (eg, in a browser) | ||||
| 	// Set to False for a "shared" cache, which is more common in a server context. | ||||
| 	PrivateCache bool | ||||
| } | ||||
|  | ||||
| // Given an HTTP Request, the future Status Code, and an ResponseWriter, | ||||
| // determine the possible reasons a response SHOULD NOT be cached. | ||||
| func CachableResponseWriter(req *http.Request, | ||||
| 	statusCode int, | ||||
| 	resp http.ResponseWriter, | ||||
| 	opts Options) ([]cacheobject.Reason, time.Time, error) { | ||||
| 	return cacheobject.UsingRequestResponse(req, statusCode, resp.Header(), opts.PrivateCache) | ||||
| } | ||||
|  | ||||
| // Given an HTTP Request and Response, determine the possible reasons a response SHOULD NOT | ||||
| // be cached. | ||||
| func CachableResponse(req *http.Request, | ||||
| 	resp *http.Response, | ||||
| 	opts Options) ([]cacheobject.Reason, time.Time, error) { | ||||
| 	return cacheobject.UsingRequestResponse(req, resp.StatusCode, resp.Header, opts.PrivateCache) | ||||
| } | ||||
							
								
								
									
										28
									
								
								vendor/github.com/pquerna/cachecontrol/cacheobject/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/pquerna/cachecontrol/cacheobject/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| load("@io_bazel_rules_go//go:def.bzl", "go_library") | ||||
|  | ||||
| go_library( | ||||
|     name = "go_default_library", | ||||
|     srcs = [ | ||||
|         "directive.go", | ||||
|         "lex.go", | ||||
|         "object.go", | ||||
|         "reasons.go", | ||||
|         "warning.go", | ||||
|     ], | ||||
|     importpath = "github.com/pquerna/cachecontrol/cacheobject", | ||||
|     visibility = ["//visibility:public"], | ||||
| ) | ||||
|  | ||||
| filegroup( | ||||
|     name = "package-srcs", | ||||
|     srcs = glob(["**"]), | ||||
|     tags = ["automanaged"], | ||||
|     visibility = ["//visibility:private"], | ||||
| ) | ||||
|  | ||||
| filegroup( | ||||
|     name = "all-srcs", | ||||
|     srcs = [":package-srcs"], | ||||
|     tags = ["automanaged"], | ||||
|     visibility = ["//visibility:public"], | ||||
| ) | ||||
							
								
								
									
										510
									
								
								vendor/github.com/pquerna/cachecontrol/cacheobject/directive.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										510
									
								
								vendor/github.com/pquerna/cachecontrol/cacheobject/directive.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,510 @@ | ||||
| /** | ||||
|  *  Copyright 2015 Paul Querna | ||||
|  * | ||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  *  you may not use this file except in compliance with the License. | ||||
|  *  You may obtain a copy of the License at | ||||
|  * | ||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  *  Unless required by applicable law or agreed to in writing, software | ||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  *  See the License for the specific language governing permissions and | ||||
|  *  limitations under the License. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| package cacheobject | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"math" | ||||
| 	"net/http" | ||||
| 	"net/textproto" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // TODO(pquerna): add extensions from here: http://www.iana.org/assignments/http-cache-directives/http-cache-directives.xhtml | ||||
|  | ||||
| var ( | ||||
| 	ErrQuoteMismatch         = errors.New("Missing closing quote") | ||||
| 	ErrMaxAgeDeltaSeconds    = errors.New("Failed to parse delta-seconds in `max-age`") | ||||
| 	ErrSMaxAgeDeltaSeconds   = errors.New("Failed to parse delta-seconds in `s-maxage`") | ||||
| 	ErrMaxStaleDeltaSeconds  = errors.New("Failed to parse delta-seconds in `min-fresh`") | ||||
| 	ErrMinFreshDeltaSeconds  = errors.New("Failed to parse delta-seconds in `min-fresh`") | ||||
| 	ErrNoCacheNoArgs         = errors.New("Unexpected argument to `no-cache`") | ||||
| 	ErrNoStoreNoArgs         = errors.New("Unexpected argument to `no-store`") | ||||
| 	ErrNoTransformNoArgs     = errors.New("Unexpected argument to `no-transform`") | ||||
| 	ErrOnlyIfCachedNoArgs    = errors.New("Unexpected argument to `only-if-cached`") | ||||
| 	ErrMustRevalidateNoArgs  = errors.New("Unexpected argument to `must-revalidate`") | ||||
| 	ErrPublicNoArgs          = errors.New("Unexpected argument to `public`") | ||||
| 	ErrProxyRevalidateNoArgs = errors.New("Unexpected argument to `proxy-revalidate`") | ||||
| ) | ||||
|  | ||||
| func whitespace(b byte) bool { | ||||
| 	if b == '\t' || b == ' ' { | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func parse(value string, cd cacheDirective) error { | ||||
| 	var err error = nil | ||||
| 	i := 0 | ||||
|  | ||||
| 	for i < len(value) && err == nil { | ||||
| 		// eat leading whitespace or commas | ||||
| 		if whitespace(value[i]) || value[i] == ',' { | ||||
| 			i++ | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		j := i + 1 | ||||
|  | ||||
| 		for j < len(value) { | ||||
| 			if !isToken(value[j]) { | ||||
| 				break | ||||
| 			} | ||||
| 			j++ | ||||
| 		} | ||||
|  | ||||
| 		token := strings.ToLower(value[i:j]) | ||||
| 		tokenHasFields := hasFieldNames(token) | ||||
| 		/* | ||||
| 			println("GOT TOKEN:") | ||||
| 			println("	i -> ", i) | ||||
| 			println("	j -> ", j) | ||||
| 			println("	token -> ", token) | ||||
| 		*/ | ||||
|  | ||||
| 		if j+1 < len(value) && value[j] == '=' { | ||||
| 			k := j + 1 | ||||
| 			// minimum size two bytes of "", but we let httpUnquote handle it. | ||||
| 			if k < len(value) && value[k] == '"' { | ||||
| 				eaten, result := httpUnquote(value[k:]) | ||||
| 				if eaten == -1 { | ||||
| 					return ErrQuoteMismatch | ||||
| 				} | ||||
| 				i = k + eaten | ||||
|  | ||||
| 				err = cd.addPair(token, result) | ||||
| 			} else { | ||||
| 				z := k | ||||
| 				for z < len(value) { | ||||
| 					if tokenHasFields { | ||||
| 						if whitespace(value[z]) { | ||||
| 							break | ||||
| 						} | ||||
| 					} else { | ||||
| 						if whitespace(value[z]) || value[z] == ',' { | ||||
| 							break | ||||
| 						} | ||||
| 					} | ||||
| 					z++ | ||||
| 				} | ||||
| 				i = z | ||||
|  | ||||
| 				result := value[k:z] | ||||
| 				if result != "" && result[len(result)-1] == ',' { | ||||
| 					result = result[:len(result)-1] | ||||
| 				} | ||||
|  | ||||
| 				err = cd.addPair(token, result) | ||||
| 			} | ||||
| 		} else { | ||||
| 			if token != "," { | ||||
| 				err = cd.addToken(token) | ||||
| 			} | ||||
| 			i = j | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // DeltaSeconds specifies a non-negative integer, representing | ||||
| // time in seconds: http://tools.ietf.org/html/rfc7234#section-1.2.1 | ||||
| // | ||||
| // When set to -1, this means unset. | ||||
| // | ||||
| type DeltaSeconds int32 | ||||
|  | ||||
| // Parser for delta-seconds, a uint31, more or less: | ||||
| // http://tools.ietf.org/html/rfc7234#section-1.2.1 | ||||
| func parseDeltaSeconds(v string) (DeltaSeconds, error) { | ||||
| 	n, err := strconv.ParseUint(v, 10, 32) | ||||
| 	if err != nil { | ||||
| 		if numError, ok := err.(*strconv.NumError); ok { | ||||
| 			if numError.Err == strconv.ErrRange { | ||||
| 				return DeltaSeconds(math.MaxInt32), nil | ||||
| 			} | ||||
| 		} | ||||
| 		return DeltaSeconds(-1), err | ||||
| 	} else { | ||||
| 		if n > math.MaxInt32 { | ||||
| 			return DeltaSeconds(math.MaxInt32), nil | ||||
| 		} else { | ||||
| 			return DeltaSeconds(n), nil | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Fields present in a header. | ||||
| type FieldNames map[string]bool | ||||
|  | ||||
| // internal interface for shared methods of RequestCacheDirectives and ResponseCacheDirectives | ||||
| type cacheDirective interface { | ||||
| 	addToken(s string) error | ||||
| 	addPair(s string, v string) error | ||||
| } | ||||
|  | ||||
| // LOW LEVEL API: Repersentation of possible request directives in a `Cache-Control` header: http://tools.ietf.org/html/rfc7234#section-5.2.1 | ||||
| // | ||||
| // Note: Many fields will be `nil` in practice. | ||||
| // | ||||
| type RequestCacheDirectives struct { | ||||
|  | ||||
| 	// max-age(delta seconds): http://tools.ietf.org/html/rfc7234#section-5.2.1.1 | ||||
| 	// | ||||
| 	// The "max-age" request directive indicates that the client is | ||||
| 	// unwilling to accept a response whose age is greater than the | ||||
| 	// specified number of seconds.  Unless the max-stale request directive | ||||
| 	// is also present, the client is not willing to accept a stale | ||||
| 	// response. | ||||
| 	MaxAge DeltaSeconds | ||||
|  | ||||
| 	// max-stale(delta seconds): http://tools.ietf.org/html/rfc7234#section-5.2.1.2 | ||||
| 	// | ||||
| 	// The "max-stale" request directive indicates that the client is | ||||
| 	// willing to accept a response that has exceeded its freshness | ||||
| 	// lifetime.  If max-stale is assigned a value, then the client is | ||||
| 	// willing to accept a response that has exceeded its freshness lifetime | ||||
| 	// by no more than the specified number of seconds.  If no value is | ||||
| 	// assigned to max-stale, then the client is willing to accept a stale | ||||
| 	// response of any age. | ||||
| 	MaxStale DeltaSeconds | ||||
|  | ||||
| 	// min-fresh(delta seconds): http://tools.ietf.org/html/rfc7234#section-5.2.1.3 | ||||
| 	// | ||||
| 	// The "min-fresh" request directive indicates that the client is | ||||
| 	// willing to accept a response whose freshness lifetime is no less than | ||||
| 	// its current age plus the specified time in seconds.  That is, the | ||||
| 	// client wants a response that will still be fresh for at least the | ||||
| 	// specified number of seconds. | ||||
| 	MinFresh DeltaSeconds | ||||
|  | ||||
| 	// no-cache(bool): http://tools.ietf.org/html/rfc7234#section-5.2.1.4 | ||||
| 	// | ||||
| 	// The "no-cache" request directive indicates that a cache MUST NOT use | ||||
| 	// a stored response to satisfy the request without successful | ||||
| 	// validation on the origin server. | ||||
| 	NoCache bool | ||||
|  | ||||
| 	// no-store(bool): http://tools.ietf.org/html/rfc7234#section-5.2.1.5 | ||||
| 	// | ||||
| 	// The "no-store" request directive indicates that a cache MUST NOT | ||||
| 	// store any part of either this request or any response to it.  This | ||||
| 	// directive applies to both private and shared caches. | ||||
| 	NoStore bool | ||||
|  | ||||
| 	// no-transform(bool): http://tools.ietf.org/html/rfc7234#section-5.2.1.6 | ||||
| 	// | ||||
| 	// The "no-transform" request directive indicates that an intermediary | ||||
| 	// (whether or not it implements a cache) MUST NOT transform the | ||||
| 	// payload, as defined in Section 5.7.2 of RFC7230. | ||||
| 	NoTransform bool | ||||
|  | ||||
| 	// only-if-cached(bool): http://tools.ietf.org/html/rfc7234#section-5.2.1.7 | ||||
| 	// | ||||
| 	// The "only-if-cached" request directive indicates that the client only | ||||
| 	// wishes to obtain a stored response. | ||||
| 	OnlyIfCached bool | ||||
|  | ||||
| 	// Extensions: http://tools.ietf.org/html/rfc7234#section-5.2.3 | ||||
| 	// | ||||
| 	// The Cache-Control header field can be extended through the use of one | ||||
| 	// or more cache-extension tokens, each with an optional value.  A cache | ||||
| 	// MUST ignore unrecognized cache directives. | ||||
| 	Extensions []string | ||||
| } | ||||
|  | ||||
| func (cd *RequestCacheDirectives) addToken(token string) error { | ||||
| 	var err error = nil | ||||
|  | ||||
| 	switch token { | ||||
| 	case "max-age": | ||||
| 		err = ErrMaxAgeDeltaSeconds | ||||
| 	case "max-stale": | ||||
| 		err = ErrMaxStaleDeltaSeconds | ||||
| 	case "min-fresh": | ||||
| 		err = ErrMinFreshDeltaSeconds | ||||
| 	case "no-cache": | ||||
| 		cd.NoCache = true | ||||
| 	case "no-store": | ||||
| 		cd.NoStore = true | ||||
| 	case "no-transform": | ||||
| 		cd.NoTransform = true | ||||
| 	case "only-if-cached": | ||||
| 		cd.OnlyIfCached = true | ||||
| 	default: | ||||
| 		cd.Extensions = append(cd.Extensions, token) | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func (cd *RequestCacheDirectives) addPair(token string, v string) error { | ||||
| 	var err error = nil | ||||
|  | ||||
| 	switch token { | ||||
| 	case "max-age": | ||||
| 		cd.MaxAge, err = parseDeltaSeconds(v) | ||||
| 		if err != nil { | ||||
| 			err = ErrMaxAgeDeltaSeconds | ||||
| 		} | ||||
| 	case "max-stale": | ||||
| 		cd.MaxStale, err = parseDeltaSeconds(v) | ||||
| 		if err != nil { | ||||
| 			err = ErrMaxStaleDeltaSeconds | ||||
| 		} | ||||
| 	case "min-fresh": | ||||
| 		cd.MinFresh, err = parseDeltaSeconds(v) | ||||
| 		if err != nil { | ||||
| 			err = ErrMinFreshDeltaSeconds | ||||
| 		} | ||||
| 	case "no-cache": | ||||
| 		err = ErrNoCacheNoArgs | ||||
| 	case "no-store": | ||||
| 		err = ErrNoStoreNoArgs | ||||
| 	case "no-transform": | ||||
| 		err = ErrNoTransformNoArgs | ||||
| 	case "only-if-cached": | ||||
| 		err = ErrOnlyIfCachedNoArgs | ||||
| 	default: | ||||
| 		// TODO(pquerna): this sucks, making user re-parse | ||||
| 		cd.Extensions = append(cd.Extensions, token+"="+v) | ||||
| 	} | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // LOW LEVEL API: Parses a Cache Control Header from a Request into a set of directives. | ||||
| func ParseRequestCacheControl(value string) (*RequestCacheDirectives, error) { | ||||
| 	cd := &RequestCacheDirectives{ | ||||
| 		MaxAge:   -1, | ||||
| 		MaxStale: -1, | ||||
| 		MinFresh: -1, | ||||
| 	} | ||||
|  | ||||
| 	err := parse(value, cd) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return cd, nil | ||||
| } | ||||
|  | ||||
| // LOW LEVEL API: Repersentation of possible response directives in a `Cache-Control` header: http://tools.ietf.org/html/rfc7234#section-5.2.2 | ||||
| // | ||||
| // Note: Many fields will be `nil` in practice. | ||||
| // | ||||
| type ResponseCacheDirectives struct { | ||||
|  | ||||
| 	// must-revalidate(bool): http://tools.ietf.org/html/rfc7234#section-5.2.2.1 | ||||
| 	// | ||||
| 	// The "must-revalidate" response directive indicates that once it has | ||||
| 	// become stale, a cache MUST NOT use the response to satisfy subsequent | ||||
| 	// requests without successful validation on the origin server. | ||||
| 	MustRevalidate bool | ||||
|  | ||||
| 	// no-cache(FieldName): http://tools.ietf.org/html/rfc7234#section-5.2.2.2 | ||||
| 	// | ||||
| 	// The "no-cache" response directive indicates that the response MUST | ||||
| 	// NOT be used to satisfy a subsequent request without successful | ||||
| 	// validation on the origin server. | ||||
| 	// | ||||
| 	// If the no-cache response directive specifies 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, any header | ||||
| 	// fields in the response that have the field-name(s) listed MUST NOT be | ||||
| 	// sent in the response to a subsequent request without successful | ||||
| 	// revalidation with the origin server. | ||||
| 	NoCache FieldNames | ||||
|  | ||||
| 	// no-cache(cast-to-bool): http://tools.ietf.org/html/rfc7234#section-5.2.2.2 | ||||
| 	// | ||||
| 	// While the RFC defines optional field-names on a no-cache directive, | ||||
| 	// many applications only want to know if any no-cache directives were | ||||
| 	// present at all. | ||||
| 	NoCachePresent bool | ||||
|  | ||||
| 	// no-store(bool): http://tools.ietf.org/html/rfc7234#section-5.2.2.3 | ||||
| 	// | ||||
| 	// The "no-store" request directive indicates that a cache MUST NOT | ||||
| 	// store any part of either this request or any response to it.  This | ||||
| 	// directive applies to both private and shared caches. | ||||
| 	NoStore bool | ||||
|  | ||||
| 	// no-transform(bool): http://tools.ietf.org/html/rfc7234#section-5.2.2.4 | ||||
| 	// | ||||
| 	// The "no-transform" response directive indicates that an intermediary | ||||
| 	// (regardless of whether it implements a cache) MUST NOT transform the | ||||
| 	// payload, as defined in Section 5.7.2 of RFC7230. | ||||
| 	NoTransform bool | ||||
|  | ||||
| 	// public(bool): http://tools.ietf.org/html/rfc7234#section-5.2.2.5 | ||||
| 	// | ||||
| 	// The "public" response directive indicates that any cache MAY store | ||||
| 	// the response, even if the response would normally be non-cacheable or | ||||
| 	// cacheable only within a private cache. | ||||
| 	Public bool | ||||
|  | ||||
| 	// private(FieldName): http://tools.ietf.org/html/rfc7234#section-5.2.2.6 | ||||
| 	// | ||||
| 	// The "private" response directive indicates that the response message | ||||
| 	// is intended for a single user and MUST NOT be stored by a shared | ||||
| 	// cache.  A private cache MAY store the response and reuse it for later | ||||
| 	// requests, even if the response would normally be non-cacheable. | ||||
| 	// | ||||
| 	// If the private response directive specifies one or more field-names, | ||||
| 	// this requirement is limited to the field-values associated with the | ||||
| 	// listed response header fields.  That is, a shared cache MUST NOT | ||||
| 	// store the specified field-names(s), whereas it MAY store the | ||||
| 	// remainder of the response message. | ||||
| 	Private FieldNames | ||||
|  | ||||
| 	// private(cast-to-bool): http://tools.ietf.org/html/rfc7234#section-5.2.2.6 | ||||
| 	// | ||||
| 	// While the RFC defines optional field-names on a private directive, | ||||
| 	// many applications only want to know if any private directives were | ||||
| 	// present at all. | ||||
| 	PrivatePresent bool | ||||
|  | ||||
| 	// proxy-revalidate(bool): http://tools.ietf.org/html/rfc7234#section-5.2.2.7 | ||||
| 	// | ||||
| 	// The "proxy-revalidate" response directive has the same meaning as the | ||||
| 	// must-revalidate response directive, except that it does not apply to | ||||
| 	// private caches. | ||||
| 	ProxyRevalidate bool | ||||
|  | ||||
| 	// max-age(delta seconds): http://tools.ietf.org/html/rfc7234#section-5.2.2.8 | ||||
| 	// | ||||
| 	// The "max-age" response directive indicates that the response is to be | ||||
| 	// considered stale after its age is greater than the specified number | ||||
| 	// of seconds. | ||||
| 	MaxAge DeltaSeconds | ||||
|  | ||||
| 	// s-maxage(delta seconds): http://tools.ietf.org/html/rfc7234#section-5.2.2.9 | ||||
| 	// | ||||
| 	// The "s-maxage" response directive indicates that, in shared caches, | ||||
| 	// the maximum age specified by this directive overrides the maximum age | ||||
| 	// specified by either the max-age directive or the Expires header | ||||
| 	// field.  The s-maxage directive also implies the semantics of the | ||||
| 	// proxy-revalidate response directive. | ||||
| 	SMaxAge DeltaSeconds | ||||
|  | ||||
| 	// Extensions: http://tools.ietf.org/html/rfc7234#section-5.2.3 | ||||
| 	// | ||||
| 	// The Cache-Control header field can be extended through the use of one | ||||
| 	// or more cache-extension tokens, each with an optional value.  A cache | ||||
| 	// MUST ignore unrecognized cache directives. | ||||
| 	Extensions []string | ||||
| } | ||||
|  | ||||
| // LOW LEVEL API: Parses a Cache Control Header from a Response into a set of directives. | ||||
| func ParseResponseCacheControl(value string) (*ResponseCacheDirectives, error) { | ||||
| 	cd := &ResponseCacheDirectives{ | ||||
| 		MaxAge:  -1, | ||||
| 		SMaxAge: -1, | ||||
| 	} | ||||
|  | ||||
| 	err := parse(value, cd) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return cd, nil | ||||
| } | ||||
|  | ||||
| func (cd *ResponseCacheDirectives) addToken(token string) error { | ||||
| 	var err error = nil | ||||
| 	switch token { | ||||
| 	case "must-revalidate": | ||||
| 		cd.MustRevalidate = true | ||||
| 	case "no-cache": | ||||
| 		cd.NoCachePresent = true | ||||
| 	case "no-store": | ||||
| 		cd.NoStore = true | ||||
| 	case "no-transform": | ||||
| 		cd.NoTransform = true | ||||
| 	case "public": | ||||
| 		cd.Public = true | ||||
| 	case "private": | ||||
| 		cd.PrivatePresent = true | ||||
| 	case "proxy-revalidate": | ||||
| 		cd.ProxyRevalidate = true | ||||
| 	case "max-age": | ||||
| 		err = ErrMaxAgeDeltaSeconds | ||||
| 	case "s-maxage": | ||||
| 		err = ErrSMaxAgeDeltaSeconds | ||||
| 	default: | ||||
| 		cd.Extensions = append(cd.Extensions, token) | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func hasFieldNames(token string) bool { | ||||
| 	switch token { | ||||
| 	case "no-cache": | ||||
| 		return true | ||||
| 	case "private": | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (cd *ResponseCacheDirectives) addPair(token string, v string) error { | ||||
| 	var err error = nil | ||||
|  | ||||
| 	switch token { | ||||
| 	case "must-revalidate": | ||||
| 		err = ErrMustRevalidateNoArgs | ||||
| 	case "no-cache": | ||||
| 		cd.NoCachePresent = true | ||||
| 		tokens := strings.Split(v, ",") | ||||
| 		if cd.NoCache == nil { | ||||
| 			cd.NoCache = make(FieldNames) | ||||
| 		} | ||||
| 		for _, t := range tokens { | ||||
| 			k := http.CanonicalHeaderKey(textproto.TrimString(t)) | ||||
| 			cd.NoCache[k] = true | ||||
| 		} | ||||
| 	case "no-store": | ||||
| 		err = ErrNoStoreNoArgs | ||||
| 	case "no-transform": | ||||
| 		err = ErrNoTransformNoArgs | ||||
| 	case "public": | ||||
| 		err = ErrPublicNoArgs | ||||
| 	case "private": | ||||
| 		cd.PrivatePresent = true | ||||
| 		tokens := strings.Split(v, ",") | ||||
| 		if cd.Private == nil { | ||||
| 			cd.Private = make(FieldNames) | ||||
| 		} | ||||
| 		for _, t := range tokens { | ||||
| 			k := http.CanonicalHeaderKey(textproto.TrimString(t)) | ||||
| 			cd.Private[k] = true | ||||
| 		} | ||||
| 	case "proxy-revalidate": | ||||
| 		err = ErrProxyRevalidateNoArgs | ||||
| 	case "max-age": | ||||
| 		cd.MaxAge, err = parseDeltaSeconds(v) | ||||
| 	case "s-maxage": | ||||
| 		cd.SMaxAge, err = parseDeltaSeconds(v) | ||||
| 	default: | ||||
| 		// TODO(pquerna): this sucks, making user re-parse, and its technically not 'quoted' like the original, | ||||
| 		// but this is still easier, just a SplitN on "=" | ||||
| 		cd.Extensions = append(cd.Extensions, token+"="+v) | ||||
| 	} | ||||
|  | ||||
| 	return err | ||||
| } | ||||
							
								
								
									
										93
									
								
								vendor/github.com/pquerna/cachecontrol/cacheobject/lex.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								vendor/github.com/pquerna/cachecontrol/cacheobject/lex.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| // Copyright 2009 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package cacheobject | ||||
|  | ||||
| // This file deals with lexical matters of HTTP | ||||
|  | ||||
| func isSeparator(c byte) bool { | ||||
| 	switch c { | ||||
| 	case '(', ')', '<', '>', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '=', '{', '}', ' ', '\t': | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func isCtl(c byte) bool { return (0 <= c && c <= 31) || c == 127 } | ||||
|  | ||||
| func isChar(c byte) bool { return 0 <= c && c <= 127 } | ||||
|  | ||||
| func isAnyText(c byte) bool { return !isCtl(c) } | ||||
|  | ||||
| func isQdText(c byte) bool { return isAnyText(c) && c != '"' } | ||||
|  | ||||
| func isToken(c byte) bool { return isChar(c) && !isCtl(c) && !isSeparator(c) } | ||||
|  | ||||
| // Valid escaped sequences are not specified in RFC 2616, so for now, we assume | ||||
| // that they coincide with the common sense ones used by GO. Malformed | ||||
| // characters should probably not be treated as errors by a robust (forgiving) | ||||
| // parser, so we replace them with the '?' character. | ||||
| func httpUnquotePair(b byte) byte { | ||||
| 	// skip the first byte, which should always be '\' | ||||
| 	switch b { | ||||
| 	case 'a': | ||||
| 		return '\a' | ||||
| 	case 'b': | ||||
| 		return '\b' | ||||
| 	case 'f': | ||||
| 		return '\f' | ||||
| 	case 'n': | ||||
| 		return '\n' | ||||
| 	case 'r': | ||||
| 		return '\r' | ||||
| 	case 't': | ||||
| 		return '\t' | ||||
| 	case 'v': | ||||
| 		return '\v' | ||||
| 	case '\\': | ||||
| 		return '\\' | ||||
| 	case '\'': | ||||
| 		return '\'' | ||||
| 	case '"': | ||||
| 		return '"' | ||||
| 	} | ||||
| 	return '?' | ||||
| } | ||||
|  | ||||
| // raw must begin with a valid quoted string. Only the first quoted string is | ||||
| // parsed and is unquoted in result. eaten is the number of bytes parsed, or -1 | ||||
| // upon failure. | ||||
| func httpUnquote(raw string) (eaten int, result string) { | ||||
| 	buf := make([]byte, len(raw)) | ||||
| 	if raw[0] != '"' { | ||||
| 		return -1, "" | ||||
| 	} | ||||
| 	eaten = 1 | ||||
| 	j := 0 // # of bytes written in buf | ||||
| 	for i := 1; i < len(raw); i++ { | ||||
| 		switch b := raw[i]; b { | ||||
| 		case '"': | ||||
| 			eaten++ | ||||
| 			buf = buf[0:j] | ||||
| 			return i + 1, string(buf) | ||||
| 		case '\\': | ||||
| 			if len(raw) < i+2 { | ||||
| 				return -1, "" | ||||
| 			} | ||||
| 			buf[j] = httpUnquotePair(raw[i+1]) | ||||
| 			eaten += 2 | ||||
| 			j++ | ||||
| 			i++ | ||||
| 		default: | ||||
| 			if isQdText(b) { | ||||
| 				buf[j] = b | ||||
| 			} else { | ||||
| 				buf[j] = '?' | ||||
| 			} | ||||
| 			eaten++ | ||||
| 			j++ | ||||
| 		} | ||||
| 	} | ||||
| 	return -1, "" | ||||
| } | ||||
							
								
								
									
										378
									
								
								vendor/github.com/pquerna/cachecontrol/cacheobject/object.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										378
									
								
								vendor/github.com/pquerna/cachecontrol/cacheobject/object.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,378 @@ | ||||
| /** | ||||
|  *  Copyright 2015 Paul Querna | ||||
|  * | ||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  *  you may not use this file except in compliance with the License. | ||||
|  *  You may obtain a copy of the License at | ||||
|  * | ||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  *  Unless required by applicable law or agreed to in writing, software | ||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  *  See the License for the specific language governing permissions and | ||||
|  *  limitations under the License. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| package cacheobject | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // LOW LEVEL API: Repersents a potentially cachable HTTP object. | ||||
| // | ||||
| // This struct is designed to be serialized efficiently, so in a high | ||||
| // performance caching server, things like Date-Strings don't need to be | ||||
| // parsed for every use of a cached object. | ||||
| type Object struct { | ||||
| 	CacheIsPrivate bool | ||||
|  | ||||
| 	RespDirectives         *ResponseCacheDirectives | ||||
| 	RespHeaders            http.Header | ||||
| 	RespStatusCode         int | ||||
| 	RespExpiresHeader      time.Time | ||||
| 	RespDateHeader         time.Time | ||||
| 	RespLastModifiedHeader time.Time | ||||
|  | ||||
| 	ReqDirectives *RequestCacheDirectives | ||||
| 	ReqHeaders    http.Header | ||||
| 	ReqMethod     string | ||||
|  | ||||
| 	NowUTC time.Time | ||||
| } | ||||
|  | ||||
| // LOW LEVEL API: Repersents the results of examinig an Object with | ||||
| // CachableObject and ExpirationObject. | ||||
| // | ||||
| // TODO(pquerna): decide if this is a good idea or bad | ||||
| type ObjectResults struct { | ||||
| 	OutReasons        []Reason | ||||
| 	OutWarnings       []Warning | ||||
| 	OutExpirationTime time.Time | ||||
| 	OutErr            error | ||||
| } | ||||
|  | ||||
| // LOW LEVEL API: Check if a object is cachable. | ||||
| func CachableObject(obj *Object, rv *ObjectResults) { | ||||
| 	rv.OutReasons = nil | ||||
| 	rv.OutWarnings = nil | ||||
| 	rv.OutErr = nil | ||||
|  | ||||
| 	switch obj.ReqMethod { | ||||
| 	case "GET": | ||||
| 		break | ||||
| 	case "HEAD": | ||||
| 		break | ||||
| 	case "POST": | ||||
| 		/** | ||||
| 		  POST: http://tools.ietf.org/html/rfc7231#section-4.3.3 | ||||
|  | ||||
| 		  Responses to POST requests are only cacheable when they include | ||||
| 		  explicit freshness information (see Section 4.2.1 of [RFC7234]). | ||||
| 		  However, POST caching is not widely implemented.  For cases where an | ||||
| 		  origin server wishes the client to be able to cache the result of a | ||||
| 		  POST in a way that can be reused by a later GET, the origin server | ||||
| 		  MAY send a 200 (OK) response containing the result and a | ||||
| 		  Content-Location header field that has the same value as the POST's | ||||
| 		  effective request URI (Section 3.1.4.2). | ||||
| 		*/ | ||||
| 		if !hasFreshness(obj.ReqDirectives, obj.RespDirectives, obj.RespHeaders, obj.RespExpiresHeader, obj.CacheIsPrivate) { | ||||
| 			rv.OutReasons = append(rv.OutReasons, ReasonRequestMethodPOST) | ||||
| 		} | ||||
|  | ||||
| 	case "PUT": | ||||
| 		rv.OutReasons = append(rv.OutReasons, ReasonRequestMethodPUT) | ||||
|  | ||||
| 	case "DELETE": | ||||
| 		rv.OutReasons = append(rv.OutReasons, ReasonRequestMethodDELETE) | ||||
|  | ||||
| 	case "CONNECT": | ||||
| 		rv.OutReasons = append(rv.OutReasons, ReasonRequestMethodCONNECT) | ||||
|  | ||||
| 	case "OPTIONS": | ||||
| 		rv.OutReasons = append(rv.OutReasons, ReasonRequestMethodOPTIONS) | ||||
|  | ||||
| 	case "TRACE": | ||||
| 		rv.OutReasons = append(rv.OutReasons, ReasonRequestMethodTRACE) | ||||
|  | ||||
| 	// HTTP Extension Methods: http://www.iana.org/assignments/http-methods/http-methods.xhtml | ||||
| 	// | ||||
| 	// To my knowledge, none of them are cachable. Please open a ticket if this is not the case! | ||||
| 	// | ||||
| 	default: | ||||
| 		rv.OutReasons = append(rv.OutReasons, ReasonRequestMethodUnkown) | ||||
| 	} | ||||
|  | ||||
| 	if obj.ReqDirectives.NoStore { | ||||
| 		rv.OutReasons = append(rv.OutReasons, ReasonRequestNoStore) | ||||
| 	} | ||||
|  | ||||
| 	// Storing Responses to Authenticated Requests: http://tools.ietf.org/html/rfc7234#section-3.2 | ||||
| 	authz := obj.ReqHeaders.Get("Authorization") | ||||
| 	if authz != "" { | ||||
| 		if obj.RespDirectives.MustRevalidate || | ||||
| 			obj.RespDirectives.Public || | ||||
| 			obj.RespDirectives.SMaxAge != -1 { | ||||
| 			// Expires of some kind present, this is potentially OK. | ||||
| 		} else { | ||||
| 			rv.OutReasons = append(rv.OutReasons, ReasonRequestAuthorizationHeader) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if obj.RespDirectives.PrivatePresent && !obj.CacheIsPrivate { | ||||
| 		rv.OutReasons = append(rv.OutReasons, ReasonResponsePrivate) | ||||
| 	} | ||||
|  | ||||
| 	if obj.RespDirectives.NoStore { | ||||
| 		rv.OutReasons = append(rv.OutReasons, ReasonResponseNoStore) | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	   the response either: | ||||
|  | ||||
| 	     *  contains an Expires header field (see Section 5.3), or | ||||
|  | ||||
| 	     *  contains a max-age response directive (see Section 5.2.2.8), or | ||||
|  | ||||
| 	     *  contains a s-maxage response directive (see Section 5.2.2.9) | ||||
| 	        and the cache is shared, or | ||||
|  | ||||
| 	     *  contains a Cache Control Extension (see Section 5.2.3) that | ||||
| 	        allows it to be cached, or | ||||
|  | ||||
| 	     *  has a status code that is defined as cacheable by default (see | ||||
| 	        Section 4.2.2), or | ||||
|  | ||||
| 	     *  contains a public response directive (see Section 5.2.2.5). | ||||
| 	*/ | ||||
|  | ||||
| 	expires := obj.RespHeaders.Get("Expires") != "" | ||||
| 	statusCachable := cachableStatusCode(obj.RespStatusCode) | ||||
|  | ||||
| 	if expires || | ||||
| 		obj.RespDirectives.MaxAge != -1 || | ||||
| 		(obj.RespDirectives.SMaxAge != -1 && !obj.CacheIsPrivate) || | ||||
| 		statusCachable || | ||||
| 		obj.RespDirectives.Public { | ||||
| 		/* cachable by default, at least one of the above conditions was true */ | ||||
| 	} else { | ||||
| 		rv.OutReasons = append(rv.OutReasons, ReasonResponseUncachableByDefault) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| var twentyFourHours = time.Duration(24 * time.Hour) | ||||
|  | ||||
| const debug = false | ||||
|  | ||||
| // LOW LEVEL API: Update an objects expiration time. | ||||
| func ExpirationObject(obj *Object, rv *ObjectResults) { | ||||
| 	/** | ||||
| 	 * Okay, lets calculate Freshness/Expiration now. woo: | ||||
| 	 *  http://tools.ietf.org/html/rfc7234#section-4.2 | ||||
| 	 */ | ||||
|  | ||||
| 	/* | ||||
| 	   o  If the cache is shared and the s-maxage response directive | ||||
| 	      (Section 5.2.2.9) is present, use its value, or | ||||
|  | ||||
| 	   o  If the max-age response directive (Section 5.2.2.8) is present, | ||||
| 	      use its value, or | ||||
|  | ||||
| 	   o  If the Expires response header field (Section 5.3) is present, use | ||||
| 	      its value minus the value of the Date response header field, or | ||||
|  | ||||
| 	   o  Otherwise, no explicit expiration time is present in the response. | ||||
| 	      A heuristic freshness lifetime might be applicable; see | ||||
| 	      Section 4.2.2. | ||||
| 	*/ | ||||
|  | ||||
| 	var expiresTime time.Time | ||||
|  | ||||
| 	if obj.RespDirectives.SMaxAge != -1 && !obj.CacheIsPrivate { | ||||
| 		expiresTime = obj.NowUTC.Add(time.Second * time.Duration(obj.RespDirectives.SMaxAge)) | ||||
| 	} else if obj.RespDirectives.MaxAge != -1 { | ||||
| 		expiresTime = obj.NowUTC.UTC().Add(time.Second * time.Duration(obj.RespDirectives.MaxAge)) | ||||
| 	} else if !obj.RespExpiresHeader.IsZero() { | ||||
| 		serverDate := obj.RespDateHeader | ||||
| 		if serverDate.IsZero() { | ||||
| 			// common enough case when a Date: header has not yet been added to an | ||||
| 			// active response. | ||||
| 			serverDate = obj.NowUTC | ||||
| 		} | ||||
| 		expiresTime = obj.NowUTC.Add(obj.RespExpiresHeader.Sub(serverDate)) | ||||
| 	} else if !obj.RespLastModifiedHeader.IsZero() { | ||||
| 		// heuristic freshness lifetime | ||||
| 		rv.OutWarnings = append(rv.OutWarnings, WarningHeuristicExpiration) | ||||
|  | ||||
| 		// http://httpd.apache.org/docs/2.4/mod/mod_cache.html#cachelastmodifiedfactor | ||||
| 		// CacheMaxExpire defaults to 24 hours | ||||
| 		// CacheLastModifiedFactor: is 0.1 | ||||
| 		// | ||||
| 		// expiry-period = MIN(time-since-last-modified-date * factor, 24 hours) | ||||
| 		// | ||||
| 		// obj.NowUTC | ||||
|  | ||||
| 		since := obj.RespLastModifiedHeader.Sub(obj.NowUTC) | ||||
| 		since = time.Duration(float64(since) * -0.1) | ||||
|  | ||||
| 		if since > twentyFourHours { | ||||
| 			expiresTime = obj.NowUTC.Add(twentyFourHours) | ||||
| 		} else { | ||||
| 			expiresTime = obj.NowUTC.Add(since) | ||||
| 		} | ||||
|  | ||||
| 		if debug { | ||||
| 			println("Now UTC: ", obj.NowUTC.String()) | ||||
| 			println("Last-Modified: ", obj.RespLastModifiedHeader.String()) | ||||
| 			println("Since: ", since.String()) | ||||
| 			println("TwentyFourHours: ", twentyFourHours.String()) | ||||
| 			println("Expiration: ", expiresTime.String()) | ||||
| 		} | ||||
| 	} else { | ||||
| 		// TODO(pquerna): what should the default behavoir be for expiration time? | ||||
| 	} | ||||
|  | ||||
| 	rv.OutExpirationTime = expiresTime | ||||
| } | ||||
|  | ||||
| // Evaluate cachability based on an HTTP request, and parts of the response. | ||||
| func UsingRequestResponse(req *http.Request, | ||||
| 	statusCode int, | ||||
| 	respHeaders http.Header, | ||||
| 	privateCache bool) ([]Reason, time.Time, error) { | ||||
|  | ||||
| 	var reqHeaders http.Header | ||||
| 	var reqMethod string | ||||
|  | ||||
| 	var reqDir *RequestCacheDirectives = nil | ||||
| 	respDir, err := ParseResponseCacheControl(respHeaders.Get("Cache-Control")) | ||||
| 	if err != nil { | ||||
| 		return nil, time.Time{}, err | ||||
| 	} | ||||
|  | ||||
| 	if req != nil { | ||||
| 		reqDir, err = ParseRequestCacheControl(req.Header.Get("Cache-Control")) | ||||
| 		if err != nil { | ||||
| 			return nil, time.Time{}, err | ||||
| 		} | ||||
| 		reqHeaders = req.Header | ||||
| 		reqMethod = req.Method | ||||
| 	} | ||||
|  | ||||
| 	var expiresHeader time.Time | ||||
| 	var dateHeader time.Time | ||||
| 	var lastModifiedHeader time.Time | ||||
|  | ||||
| 	if respHeaders.Get("Expires") != "" { | ||||
| 		expiresHeader, err = http.ParseTime(respHeaders.Get("Expires")) | ||||
| 		if err != nil { | ||||
| 			// sometimes servers will return `Expires: 0` or `Expires: -1` to | ||||
| 			// indicate expired content | ||||
| 			expiresHeader = time.Time{} | ||||
| 		} | ||||
| 		expiresHeader = expiresHeader.UTC() | ||||
| 	} | ||||
|  | ||||
| 	if respHeaders.Get("Date") != "" { | ||||
| 		dateHeader, err = http.ParseTime(respHeaders.Get("Date")) | ||||
| 		if err != nil { | ||||
| 			return nil, time.Time{}, err | ||||
| 		} | ||||
| 		dateHeader = dateHeader.UTC() | ||||
| 	} | ||||
|  | ||||
| 	if respHeaders.Get("Last-Modified") != "" { | ||||
| 		lastModifiedHeader, err = http.ParseTime(respHeaders.Get("Last-Modified")) | ||||
| 		if err != nil { | ||||
| 			return nil, time.Time{}, err | ||||
| 		} | ||||
| 		lastModifiedHeader = lastModifiedHeader.UTC() | ||||
| 	} | ||||
|  | ||||
| 	obj := Object{ | ||||
| 		CacheIsPrivate: privateCache, | ||||
|  | ||||
| 		RespDirectives:         respDir, | ||||
| 		RespHeaders:            respHeaders, | ||||
| 		RespStatusCode:         statusCode, | ||||
| 		RespExpiresHeader:      expiresHeader, | ||||
| 		RespDateHeader:         dateHeader, | ||||
| 		RespLastModifiedHeader: lastModifiedHeader, | ||||
|  | ||||
| 		ReqDirectives: reqDir, | ||||
| 		ReqHeaders:    reqHeaders, | ||||
| 		ReqMethod:     reqMethod, | ||||
|  | ||||
| 		NowUTC: time.Now().UTC(), | ||||
| 	} | ||||
| 	rv := ObjectResults{} | ||||
|  | ||||
| 	CachableObject(&obj, &rv) | ||||
| 	if rv.OutErr != nil { | ||||
| 		return nil, time.Time{}, rv.OutErr | ||||
| 	} | ||||
|  | ||||
| 	ExpirationObject(&obj, &rv) | ||||
| 	if rv.OutErr != nil { | ||||
| 		return nil, time.Time{}, rv.OutErr | ||||
| 	} | ||||
|  | ||||
| 	return rv.OutReasons, rv.OutExpirationTime, nil | ||||
| } | ||||
|  | ||||
| // calculate if a freshness directive is present: http://tools.ietf.org/html/rfc7234#section-4.2.1 | ||||
| func hasFreshness(reqDir *RequestCacheDirectives, respDir *ResponseCacheDirectives, respHeaders http.Header, respExpires time.Time, privateCache bool) bool { | ||||
| 	if !privateCache && respDir.SMaxAge != -1 { | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| 	if respDir.MaxAge != -1 { | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| 	if !respExpires.IsZero() || respHeaders.Get("Expires") != "" { | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func cachableStatusCode(statusCode int) bool { | ||||
| 	/* | ||||
| 		Responses with status codes that are defined as cacheable by default | ||||
| 		(e.g., 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, and 501 in | ||||
| 		this specification) can be reused by a cache with heuristic | ||||
| 		expiration unless otherwise indicated by the method definition or | ||||
| 		explicit cache controls [RFC7234]; all other status codes are not | ||||
| 		cacheable by default. | ||||
| 	*/ | ||||
| 	switch statusCode { | ||||
| 	case 200: | ||||
| 		return true | ||||
| 	case 203: | ||||
| 		return true | ||||
| 	case 204: | ||||
| 		return true | ||||
| 	case 206: | ||||
| 		return true | ||||
| 	case 300: | ||||
| 		return true | ||||
| 	case 301: | ||||
| 		return true | ||||
| 	case 404: | ||||
| 		return true | ||||
| 	case 405: | ||||
| 		return true | ||||
| 	case 410: | ||||
| 		return true | ||||
| 	case 414: | ||||
| 		return true | ||||
| 	case 501: | ||||
| 		return true | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										95
									
								
								vendor/github.com/pquerna/cachecontrol/cacheobject/reasons.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								vendor/github.com/pquerna/cachecontrol/cacheobject/reasons.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| /** | ||||
|  *  Copyright 2015 Paul Querna | ||||
|  * | ||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  *  you may not use this file except in compliance with the License. | ||||
|  *  You may obtain a copy of the License at | ||||
|  * | ||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  *  Unless required by applicable law or agreed to in writing, software | ||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  *  See the License for the specific language governing permissions and | ||||
|  *  limitations under the License. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| package cacheobject | ||||
|  | ||||
| // Repersents a potential Reason to not cache an object. | ||||
| // | ||||
| // Applications may wish to ignore specific reasons, which will make them non-RFC | ||||
| // compliant, but this type gives them specific cases they can choose to ignore, | ||||
| // making them compliant in as many cases as they can. | ||||
| type Reason int | ||||
|  | ||||
| const ( | ||||
|  | ||||
| 	// The request method was POST and an Expiration header was not supplied. | ||||
| 	ReasonRequestMethodPOST Reason = iota | ||||
|  | ||||
| 	// The request method was PUT and PUTs are not cachable. | ||||
| 	ReasonRequestMethodPUT | ||||
|  | ||||
| 	// The request method was DELETE and DELETEs are not cachable. | ||||
| 	ReasonRequestMethodDELETE | ||||
|  | ||||
| 	// The request method was CONNECT and CONNECTs are not cachable. | ||||
| 	ReasonRequestMethodCONNECT | ||||
|  | ||||
| 	// The request method was OPTIONS and OPTIONS are not cachable. | ||||
| 	ReasonRequestMethodOPTIONS | ||||
|  | ||||
| 	// The request method was TRACE and TRACEs are not cachable. | ||||
| 	ReasonRequestMethodTRACE | ||||
|  | ||||
| 	// The request method was not recognized by cachecontrol, and should not be cached. | ||||
| 	ReasonRequestMethodUnkown | ||||
|  | ||||
| 	// The request included an Cache-Control: no-store header | ||||
| 	ReasonRequestNoStore | ||||
|  | ||||
| 	// The request included an Authorization header without an explicit Public or Expiration time: http://tools.ietf.org/html/rfc7234#section-3.2 | ||||
| 	ReasonRequestAuthorizationHeader | ||||
|  | ||||
| 	// The response included an Cache-Control: no-store header | ||||
| 	ReasonResponseNoStore | ||||
|  | ||||
| 	// The response included an Cache-Control: private header and this is not a Private cache | ||||
| 	ReasonResponsePrivate | ||||
|  | ||||
| 	// The response failed to meet at least one of the conditions specified in RFC 7234 section 3: http://tools.ietf.org/html/rfc7234#section-3 | ||||
| 	ReasonResponseUncachableByDefault | ||||
| ) | ||||
|  | ||||
| func (r Reason) String() string { | ||||
| 	switch r { | ||||
| 	case ReasonRequestMethodPOST: | ||||
| 		return "ReasonRequestMethodPOST" | ||||
| 	case ReasonRequestMethodPUT: | ||||
| 		return "ReasonRequestMethodPUT" | ||||
| 	case ReasonRequestMethodDELETE: | ||||
| 		return "ReasonRequestMethodDELETE" | ||||
| 	case ReasonRequestMethodCONNECT: | ||||
| 		return "ReasonRequestMethodCONNECT" | ||||
| 	case ReasonRequestMethodOPTIONS: | ||||
| 		return "ReasonRequestMethodOPTIONS" | ||||
| 	case ReasonRequestMethodTRACE: | ||||
| 		return "ReasonRequestMethodTRACE" | ||||
| 	case ReasonRequestMethodUnkown: | ||||
| 		return "ReasonRequestMethodUnkown" | ||||
| 	case ReasonRequestNoStore: | ||||
| 		return "ReasonRequestNoStore" | ||||
| 	case ReasonRequestAuthorizationHeader: | ||||
| 		return "ReasonRequestAuthorizationHeader" | ||||
| 	case ReasonResponseNoStore: | ||||
| 		return "ReasonResponseNoStore" | ||||
| 	case ReasonResponsePrivate: | ||||
| 		return "ReasonResponsePrivate" | ||||
| 	case ReasonResponseUncachableByDefault: | ||||
| 		return "ReasonResponseUncachableByDefault" | ||||
| 	} | ||||
|  | ||||
| 	panic(r) | ||||
| } | ||||
							
								
								
									
										107
									
								
								vendor/github.com/pquerna/cachecontrol/cacheobject/warning.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								vendor/github.com/pquerna/cachecontrol/cacheobject/warning.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | ||||
| /** | ||||
|  *  Copyright 2015 Paul Querna | ||||
|  * | ||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  *  you may not use this file except in compliance with the License. | ||||
|  *  You may obtain a copy of the License at | ||||
|  * | ||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  *  Unless required by applicable law or agreed to in writing, software | ||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  *  See the License for the specific language governing permissions and | ||||
|  *  limitations under the License. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| package cacheobject | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // Repersents an HTTP Warning: http://tools.ietf.org/html/rfc7234#section-5.5 | ||||
| type Warning int | ||||
|  | ||||
| const ( | ||||
| 	// Response is Stale | ||||
| 	// A cache SHOULD generate this whenever the sent response is stale. | ||||
| 	WarningResponseIsStale Warning = 110 | ||||
|  | ||||
| 	// Revalidation Failed | ||||
| 	// A cache SHOULD generate this when sending a stale | ||||
| 	// response because an attempt to validate the response failed, due to an | ||||
| 	// inability to reach the server. | ||||
| 	WarningRevalidationFailed Warning = 111 | ||||
|  | ||||
| 	// Disconnected Operation | ||||
| 	// A cache SHOULD generate this if it is intentionally disconnected from | ||||
| 	// the rest of the network for a period of time. | ||||
| 	WarningDisconnectedOperation Warning = 112 | ||||
|  | ||||
| 	// Heuristic Expiration | ||||
| 	// | ||||
| 	// A cache SHOULD generate this if it heuristically chose a freshness | ||||
| 	// lifetime greater than 24 hours and the response's age is greater than | ||||
| 	// 24 hours. | ||||
| 	WarningHeuristicExpiration Warning = 113 | ||||
|  | ||||
| 	// Miscellaneous Warning | ||||
| 	// | ||||
| 	// The warning text can include arbitrary information to be presented to | ||||
| 	// a human user or logged.  A system receiving this warning MUST NOT | ||||
| 	// take any automated action, besides presenting the warning to the | ||||
| 	// user. | ||||
| 	WarningMiscellaneousWarning Warning = 199 | ||||
|  | ||||
| 	// Transformation Applied | ||||
| 	// | ||||
| 	// This Warning code MUST be added by a proxy if it applies any | ||||
| 	// transformation to the representation, such as changing the | ||||
| 	// content-coding, media-type, or modifying the representation data, | ||||
| 	// unless this Warning code already appears in the response. | ||||
| 	WarningTransformationApplied Warning = 214 | ||||
|  | ||||
| 	// Miscellaneous Persistent Warning | ||||
| 	// | ||||
| 	// The warning text can include arbitrary information to be presented to | ||||
| 	// a human user or logged.  A system receiving this warning MUST NOT | ||||
| 	// take any automated action. | ||||
| 	WarningMiscellaneousPersistentWarning Warning = 299 | ||||
| ) | ||||
|  | ||||
| func (w Warning) HeaderString(agent string, date time.Time) string { | ||||
| 	if agent == "" { | ||||
| 		agent = "-" | ||||
| 	} else { | ||||
| 		// TODO(pquerna): this doesn't escape agent if it contains bad things. | ||||
| 		agent = `"` + agent + `"` | ||||
| 	} | ||||
| 	return fmt.Sprintf(`%d %s "%s" %s`, w, agent, w.String(), date.Format(http.TimeFormat)) | ||||
| } | ||||
|  | ||||
| func (w Warning) String() string { | ||||
| 	switch w { | ||||
| 	case WarningResponseIsStale: | ||||
| 		return "Response is Stale" | ||||
| 	case WarningRevalidationFailed: | ||||
| 		return "Revalidation Failed" | ||||
| 	case WarningDisconnectedOperation: | ||||
| 		return "Disconnected Operation" | ||||
| 	case WarningHeuristicExpiration: | ||||
| 		return "Heuristic Expiration" | ||||
| 	case WarningMiscellaneousWarning: | ||||
| 		// TODO(pquerna): ideally had a better way to override this one code. | ||||
| 		return "Miscellaneous Warning" | ||||
| 	case WarningTransformationApplied: | ||||
| 		return "Transformation Applied" | ||||
| 	case WarningMiscellaneousPersistentWarning: | ||||
| 		// TODO(pquerna): same as WarningMiscellaneousWarning | ||||
| 		return "Miscellaneous Persistent Warning" | ||||
| 	} | ||||
|  | ||||
| 	panic(w) | ||||
| } | ||||
							
								
								
									
										25
									
								
								vendor/github.com/pquerna/cachecontrol/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								vendor/github.com/pquerna/cachecontrol/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| /** | ||||
|  *  Copyright 2015 Paul Querna | ||||
|  * | ||||
|  *  Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  *  you may not use this file except in compliance with the License. | ||||
|  *  You may obtain a copy of the License at | ||||
|  * | ||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  *  Unless required by applicable law or agreed to in writing, software | ||||
|  *  distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  *  See the License for the specific language governing permissions and | ||||
|  *  limitations under the License. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| // Package cachecontrol implements the logic for HTTP Caching | ||||
| // | ||||
| // Deciding if an HTTP Response can be cached is often harder | ||||
| // and more bug prone than an actual cache storage backend. | ||||
| // cachecontrol provides a simple interface to determine if | ||||
| // request and response pairs are cachable as defined under | ||||
| // RFC 7234 http://tools.ietf.org/html/rfc7234 | ||||
| package cachecontrol | ||||
		Reference in New Issue
	
	Block a user