// Tack starts a fresh "this second Epoch". It does not mean it lasts a // second, it's mere resolution limitation. Given a "Tack" all following // events receive monotonically increasing "Ticks". If Tack detects // that last second is still up it does not reset the "Ticks" counter. func (o *uniq) Tack() os.Error { var sec string var cnt uint16 // stamp := time.Format("2006 Jan 02 | 05 04 15 MST (-0700)") var err tdb.Error meta := db[META+EXT] // GLOBAL ENV rox! store := true // ahh, those intermunged concerns... if meta == nil { return os.NewError("uniq.Tack(): nil META db") } else { o.utc = time.UTC() o.sec = strconv.Itob64(o.utc.Seconds(), BASE) var cnt_s string if sec, err = meta.Fetch(NOW); err == nil { // trin // f**k // order if o.sec == sec { if cnt_s, err = meta.Fetch(CNT); err == nil { cnt_ugh, _ := strconv.Btoui64(cnt_s, BASE) cnt = uint16(cnt_ugh) if cnt > o.cnt { o.cnt = cnt store = false } } } else { o.cnt = 0 } } // TODO tdb.Exists() if store { if err = meta.Store(NOW, o.sec, tdb.MODIFY); err != nil { // presumably it yet exists not... if err = meta.Store(NOW, o.sec, tdb.INSERT); err != nil { return err } } // lazy logic. cnt_s = strconv.Itob64(int64(o.cnt), BASE) // mip map if err = meta.Store(CNT, cnt_s, tdb.MODIFY); err != nil { // presumably it yet exists not... if err = meta.Store(CNT, cnt_s, tdb.INSERT); err != nil { return err } } } } return nil }
// Encode x as an octal ASCII string and write it into b with leading zeros. func (tw *Writer) octal(b []byte, x int64) { s := strconv.Itob64(x, 8) // leading zeros, but leave room for a NUL. for len(s)+1 < len(b) { s = "0" + s } tw.cString(b, s) }
// Write x into b, either as octal or as binary (GNUtar/star extension). func (tw *Writer) numeric(b []byte, x int64) { // Try octal first. s := strconv.Itob64(x, 8) if len(s) < len(b) { tw.octal(b, x) return } // Too big: use binary (big-endian). tw.usedBinary = true for i := len(b) - 1; x > 0 && i >= 0; i-- { b[i] = byte(x) x >>= 8 } b[0] |= 0x80 // highest bit indicates binary format }
// ServeFile responds to the request with the contents of the named file. // // If the "v" request parameter is set, then ServeFile sets the expires header // and the cache control maximum age parameter to ten years in the future. func ServeFile(req *Request, fname string, options *ServeFileOptions) { if options == nil { options = &defaultServeFileOptions } f, err := os.Open(fname) if err != nil { req.Error(StatusNotFound, err) return } defer f.Close() info, err := f.Stat() if err != nil || !info.IsRegular() { req.Error(StatusNotFound, err) return } status := StatusOK header := Header{} if options.Header != nil { for k, v := range options.Header { header[k] = v } } etag := strconv.Itob64(info.Mtime_ns, 36) header.Set(HeaderETag, QuoteHeaderValue(etag)) for _, qetag := range req.Header.GetList(HeaderIfNoneMatch) { if etag == UnquoteHeaderValue(qetag) { status = StatusNotModified break } } if status == StatusNotModified { // Clear entity headers. for k, _ := range header { if strings.HasPrefix(k, "Content-") { header[k] = nil, false } } } else { // Set entity headers header.Set(HeaderContentLength, strconv.Itoa64(info.Size)) if _, found := header[HeaderContentType]; !found { ext := path.Ext(fname) contentType := "" if options.MimeType != nil { contentType = options.MimeType[ext] } if contentType == "" { contentType = mime.TypeByExtension(ext) } if contentType != "" { header.Set(HeaderContentType, contentType) } } } if v := req.Param.Get("v"); v != "" { parts := header.GetList(HeaderCacheControl) i := 0 for _, part := range parts { if strings.HasPrefix(part, "max-age=") { continue } parts[i] = part i += 1 } if i != len(parts) { parts = parts[:i] } const maxAge = 60 * 60 * 24 * 365 * 10 header.Set(HeaderExpires, FormatDeltaSeconds(maxAge)) header.Set(HeaderCacheControl, strings.Join(append(parts, "max-age="+strconv.Itoa(maxAge)), ", ")) } w := req.Responder.Respond(status, header) if req.Method != "HEAD" && status != StatusNotModified { io.Copy(w, f) } }
// SignValue returns a string containing value, an expiration time and a // signature. The expiration time is computed from the current time and // maxAgeSeconds. The signature is an HMAC SHA-1 signature of value, context // and the expiration time. Use the function VerifyValue to extract the value, // check the expiration time and verify the signature. // // SignValue can be used to store credentials in a cookie: // // var secret string // Initialized by application // const uidCookieMaxAge = 3600 * 24 * 30 // // // uidCookieValue returns the Set-Cookie header value containing a // // signed and timestamped user id. // func uidCookieValue(uid string) string { // s := web.SignValue(secret, "uid", uidCookieMaxAge, uid) // return web.NewCookie("uid", s).MaxAge(uidCookieMaxAge).String() // } // // // requestUid returns the user id from the request cookie. An error // // is returned if the cookie is missing, the value has expired or the // // signature is not valid. // func requestUid(req *web.Request) (string, os.Error) { // return web.VerifyValue(secret, "uid", req.Cookie.Get("uid")) // } func SignValue(secret, context string, maxAgeSeconds int, value string) string { expiration := strconv.Itob64(time.Seconds()+int64(maxAgeSeconds), 16) sig := signature(secret, context, expiration, value) return sig + "~" + expiration + "~" + value }
func (e DecodeError) String() string { return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.Itob64(int64(e.Offset), 16) + ": " + e.Error }
// Tick ticks me off... we should store each one in db or will well clubber // himself on Tack. But for now... we Tack once per forkproc and Tick in hopes // ... oh, we can always Tack on exit... // func (o *uniq) Tick() string { cnt_s := strconv.Itob64(int64(o.cnt), BASE) o.cnt++ return o.sec + "." + cnt_s }
func computeTestEtag() string { info, _ := os.Stat("handlers_test.go") return QuoteHeaderValue(strconv.Itob64(info.Mtime_ns, 36)) }