rob05c commented on a change in pull request #4942:
URL: https://github.com/apache/trafficcontrol/pull/4942#discussion_r485218928



##########
File path: traffic_ops/traffic_ops_golang/api/api.go
##########
@@ -994,3 +994,36 @@ func CreateDeprecationAlerts(alternative *string) 
tc.Alerts {
                return tc.CreateAlerts(tc.WarnLevel, "This endpoint is 
deprecated, and will be removed in the future")
        }
 }
+
+// GetLastUpdated checks for the resource in the database, and returns its 
last_updated timestamp, if available.
+func GetLastUpdated(tx *sqlx.Tx, ID int, tableName string) (*tc.TimeNoMod, 
error) {
+       lastUpdated := tc.TimeNoMod{}
+       rows, err := tx.Query(`select last_updated from `+tableName+` where 
id=$1`, ID)
+       if err != nil {
+               return nil, err
+       }
+       defer rows.Close()
+       if !rows.Next() {
+               return nil, errors.New("no resource found with this id")
+       }
+       if err := rows.Scan(&lastUpdated); err != nil {
+               return nil, err
+       }
+       return &lastUpdated, nil
+}
+
+// IsUnmodified returns a boolean, saying whether or not the resource in 
question was modified since the time specified in the headers.
+func IsUnmodified(h http.Header, existingLastUpdated *tc.TimeNoMod) bool {
+       _, iumsTime := rfc.GetETagOrIfUnmodifiedSinceTime(h)
+       existingEtag := rfc.ETag(existingLastUpdated.Time)
+
+       if h != nil {
+               if h.Get(rfc.IfMatch) != "" && 
!strings.Contains(h.Get(rfc.IfMatch), existingEtag) {

Review comment:
       Maybe something like 
   ```
   func GetUnmodifiedTime(h http.Header) (time.Time, bool) {
        if h == nil {
                return time.Time{}, false
        }
        if im := h.Get(IfMatch); im != "" {
                if et, ok := ParseETags(strings.Split(im, ",")); ok {
                        return et, true
                }
        }
        if ius := h.Get(IfUnmodifiedSince); ius != "" {
                if tm, ok := ParseHTTPDate(ius); ok {
                        return tm, true
                }
        }
        return time.Time{}, false
   }
   
   // ParseETags the latest time of any valid ETag, and whether a valid ETag 
was found.
   func ParseETags(eTags []string) (time.Time, bool) {
        latestTime := time.Time{}
        for _, tag := range eTags {
                tag = strings.TrimSpace(tag)
                et, err := ParseETag(tag)
                // errors are recoverable, keep going through the list of etags
                if err != nil {
                        continue
                }
                if et.After(latestTime) {
                        latestTime = et
                }
        }
        if latestTime == (time.Time{}) {
                return time.Time{}, false
        }
        return latestTime, true
   }
   
   // IsUnmodified returns a boolean, saying whether or not the resource in 
question was modified since the time specified in the headers.
   func IsUnmodified(h http.Header, lastUpdated time.Time) bool {
        unmodifiedTime, ok := rfc.GetUnmodifiedTime(h)
        if !ok {
                return true // no IUS/IM header: consider unmodified
        }
        return !lastUpdated.After(unmodifiedTime)
   }
   ```
   ?
   
   That would protect us against edge cases and future ETag changes, which will 
be contained in the `ParseETag` func




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to