I don't think it is good to return 'static

I have this code to return an HTTP Cookie which is annotated with 'static. It compiles and runs, but I think annotating the return value with 'static not a good way. So, how can I fix it?

pub fn build_cookie(jwt: String) -> Cookie<'static> {
    let cookie = Cookie::build(SECURITY_ACCESS_JWT_COOKIE_NAME, jwt)
        .domain(SECURITY_ACCESS_JWT_COOKIE_DOMAIN)
        .path(SECURITY_ACCESS_JWT_COOKIE_PATH)
        .secure(true)
        .http_only(true)
        .expires(time::now().add(Duration::days(30)))
        .finish();
    cookie
}

I'm using actix_web and jsonwebtoken.

it's pretty uncommon too see this! makes me wonder what in the internal implementation of Cookie makes this necessary…

however, the CookieBuilder::finish() method returns Cookie<'static> so i don't think there's a choice other than to pass the return type on

Looking at the code, it seems like Cookie can either store its own data, or store a reference to some other data (e.g. a reference to a slice of the original HTTP data). This allows it to avoid cloning strings in some cases, which can be a big boost to performance.

That's why you have to specify a lifetime - 'static is saying that it doesn't rely on the lifetime of any other data, whereas 'a (or something similar) would mean it would be tied to something else.

1 Like

Specifically what do you think is intrinsically bad about returning a type with a 'static lifetime parameter?

1 Like

'static means it is going to exist throughout the execution of the application. The Cookie is specific to the particular HTTP request and it is not needed after it has been returned as an HTTP response (ie. the Cookie becomes useless after it is returned in an HTTP response). Besides, there will be many simultaneous HTTP requests/responses and thus many Cookies being created and returned.

'static in the structure, i.e. the owned value, means not that it will exist until the application exit, but that in can exist (contrary to the references, which must remain valid). There's no harm in dropping the 'static owned value prematurely - you simply don't force yourself to do it.

4 Likes

That all depends on how you create it. If for instance you create a struct that contains a reference to a string literal, it can have the 'static lifetime associated with it, yet it won't magically keep "recreating" the string literal and eating your memory.

Now if you are taking some otherwise non-static data and extending its lifetime in a way that it does stick around, e.g. using Box::leak, then yes, you might have a memory leak problem. However, this doesn't have anything to do with the lifetime annotation. It all boils down to how you store (or don't store) objects throughout your program. 'static doesn't keep any value alive.

1 Like

Just think "unbound" rather than whatever you imagine static as usually signifying.

A default specification would be nice to avoid verbosity. You can do so with type parameter but not lifetime.
X<'a = 'static>

1 Like

It's fine. The function doesn't take any references at all, so it doesn't have any other lifetime to use for the Cookie type. The only lifetime you can make out of thin air is 'static.

And in this case it's valid, because the Cookie is fully owned and doesn't depend on any other data. It's the same as Cow<'a, str> that can be Cow<'static, str> when you convert it from String.

2 Likes