Hi Mark, Whether or not your proxy is caching, you may find RFC7234[1] relevant in addressing some of your questions (as well as many you may later encounter). I think you may find section 5.2 to be of particular interest, though any proxy author should be familiar with the full text.
Op di 6 aug. 2019 om 05:14 schreef <mark.m...@gmail.com>: > > Hello, > > I'm using Go's standard library reverse proxy and I'm trying to figure out if > the standard library HTTP web server (e.g. http.ListenAndServe) implements > the relevant conditional request handling logic for ETag/Last-Modified > headers. > > I did some Googling and noticed the HTTP file system request handler > (https://golang.org/src/net/http/fs.go) does implement that logic, but I > couldn't find the same for the HTTP web server. > > I also couldn't find any examples of setting ETags/Last-Modified (other than > this basic implementation for setting ETags: > https://github.com/go-http-utils/etag/blob/master/etag.go). > > What's confusing me there is the concept of "strong" and "weak" validation > and how certain scenarios might influence whether an ETag is marked as either > strong or weak (depending on the implementation -- see > https://developer.mozilla.org/en-US/docs/Web/HTTP/Conditional_requests#Validators). > > So to recap, my questions are (and I appreciate some of these are outside the > scope of just Go -- so apologies if that's not allowed in this forum): I think this is a fine question for this list, which isn't necessarily constrained to questions about Go, but also for how to achieve things while using Go. Lines get blurred since many technologies touch each other. I don't think any apologies are necessary :). > 1. Should I set ETag/Last-Modified in a proxy? Last-Modified feels like it's > not the responsibility of the proxy but the origin, where as an ETag is > something I feel is "ok" to do in the proxy as a 'fallback' (as we already > set 'serve stale' caching headers on behalf of our origins if they neglect to > include them). ETag and Last-Modified should be sent by the origin to any proxy to let the proxy know when the content is stale (assuming the proxy is caching). The only case in which a proxy might set these things is if there are configurations provided by the content owner that allow the proxy to determine what the lifetime of the response object is outside of response headers. This is most useful in cases where the content is synthetically generated by the proxy as a result of the content owner's configuration. If you don't have such a system in place, your proxy should never be generating these response headers, and you should be working with your customers / users to help them understand when to set cache control headers. > 2. Do I need to implement `If-None-Match` and `If-Modified-Since` behaviours > myself (i.e. is it not provided by the Go standard library's HTTP web server)? Unless you're serving from the filesystem handler (which does implement IMS/INM), you'll need to implement these yourself. Note that you _could_ simply proxy this to the origin and let it handle the validation. This is often overkill for what people actually need, but it is guaranteed to work. One trick that many CDN providers leverage is to offer their customers the option to serve the stale object while revalidating it. If that option is set, an asynchronous revalidation request is spawned -- new requests are blocked on the completion of that request -- and the potentially stale content is served to the original requester without blocking that request on revalidation. > 3. I was planning on setting an ETag header on the response from within > httputil.ReverseProxy#ModifyResponse but wasn't sure if that would be the > correct place to set it. It's unclear to me why you should be setting an etag header if you're a proxy. > 4. What constitutes a strong/weak validator (e.g. would a simple hash > function generating a digest of the URL path + response body suffice)? A hash function over the body of the response would constitute strong validation. I'm not sure why you'd need to mix in the path; there's nothing wrong with serving the exact same content between two endpoints, and the ETag is tied to a response object. Weak validation is signified by an additional "W/" in the etag identifier. In practice, this means that you mustn't use weak identifiers for serving byte-range requests. Weak identifiers may be more useful for dynamically generated content where you might for example have a date added in, or an ad server link that is rotated each time the page is served, or a counter, or something like this. An example of weak validation would be something that is version and encoding based -- each time the content changes materially, you'd increment the version, and some identifier for the content-encoding would also be mixed in. > Thanks for any help/insights/opinions y'all can share with me. > > Kind regards, > Mark > Hope that helps! Kind regards, --dho [1]: https://tools.ietf.org/html/rfc7234 -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAFgOgC9d6vsQFe5A8ZHY31QiQNTFqefqDTOGQbXLCQvf-zWpKA%40mail.gmail.com.