Giter Site home page Giter Site logo

cookie-rs's Introduction

Cookie

CI Status Current Crates.io Version Documentation

A Rust library for parsing HTTP cookies and managing cookie jars.

Usage

Add the following to your Cargo.toml:

[dependencies]
cookie = "0.18"

See the documentation for detailed usage information.

Minimum Supported Rust Version (MSRV)

Version Range MSRV
cookie == 0.18 rustc 1.56
0.16 <= cookie <= 0.17 rustc 1.53
cookie <= 0.15 rustc 1.41

License

This project is licensed under your option of either of the following:

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in cookie by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

cookie-rs's People

Contributors

aatxe avatar alex avatar alexcrichton avatar alexreg avatar atouchet avatar briansmith avatar davidpdrsn avatar ddefisher avatar djc avatar dlrobertson avatar eijebong avatar erickt avatar finnbear avatar frewsxcv avatar golddranks avatar hartshorne avatar jakubadamw avatar jdm avatar jebrosen avatar jedenastka avatar paolobarbolini avatar retep998 avatar s-panferov avatar seanmonstar avatar sergiobenitez avatar spk avatar tarcieri avatar ubnt-intrepid avatar untitaker avatar wezm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cookie-rs's Issues

Use Z85 encoding HMAC values and encrypted values

Z85 is like Base64, but instead of encoding 3 bytes in 4 ASCII characters, it encodes 4 bytes in 5 ASCII characters. The constraints placed on the design of Z85 also happen to make every Z85 encoding character a valid cookie value character. (Valid values in a cookie value are documented as cookie-octet in RFC 6265 Section 4.1.1.

In the case of HMAC-SHA256-signed , this would reduce 12 bytes of base64-encoding overhead to 8 bytes of Z85 encoding overhead, which isn't really significant. For encrypted-and-signed cookies the savings could be more significant.

This would remove the rustc-serialize dependency, which also seems desirable. (This could also be done by switching to the base64 crate or an alternative.)

jar::CookieJar::iter test fails on Fedora

failures:

---- src/jar.rs - jar::CookieJar::iter (line 320) stdout ----
thread 'src/jar.rs - jar::CookieJar::iter (line 320)' panicked at 'test executable failed:

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `4`,
 right: `3`', src/jar.rs:19:1
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

', src/librustdoc/test.rs:372:17
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.


failures:
    src/jar.rs - jar::CookieJar::iter (line 320)

Implement Send?

Can/should the CookieJar type (unsafely) implement Send? Or perhaps one of its component types. It's rather prohibitive right now that it doesn't.

Feature: Sign entire cookie, not just value

I'd like signatures on cookies to include expiration date and path as well. The signature could still be inside the cookie value.

I would love to prepare a PR for this, but I'm unsure how to design this in a backwards compat way (or if that is even necessary).

Release with updated dependency

Thanks for the great framework.
I am trying to use merkle tree from spinresearch but i am getting a dependency error.

error: failed to select a version for ring.
... required by package merkle v1.11.0
... which is depended on by filtering-service v0.1.0 (/Users/alakazam/Documents/projects/RUST/filtering-service)
versions that meet the requirements ^0.16.1 are: 0.16.9, 0.16.7, 0.16.6, 0.16.5, 0.16.4, 0.16.3, 0.16.2, 0.16.1

the package ring links to the native library ring-asm, but it conflicts with a previous package which links to ring-asm as well:
package ring v0.13.5
... which is depended on by cookie v0.11.0
... which is depended on by rocket_http v0.4.2
... which is depended on by rocket v0.4.2
... which is depended on by filtering-service v0.1.0 (/Users/alakazam/Documents/projects/RUST/filtering-service)

failed to select a version for ring which could resolve this conflict.

I tried using replace also but didnt work for me. Please can we do something @SergioBenitez @jebrosen

Please separate "secure" feature into a different crate

I realize its an optional feature, but even libraries that don't care care about signing cookies are still disrupted when breaking changes of ring are released (for example, seanmonstar/reqwest#517). If they were separate crates, the core Cookie API could be more stable, and then only cookie-secure (naming is hard) would ever need to update for new ring versions.

Use an AEAD cipher instead of AES-CBC + HMAC-SHA1

cookie-rs currently uses AES-256-CBC and then HMAC-SHA1 in encrypt-then-MAC. This is secure, since AES-256-CBC and HMAC-SHA1 are both individually secure and because they are used in encrypt-then-MAC.

However, neither AES-256-CBC nor HMAC-SHA1 is fast, even when AES is hardware accelerated (due to the serial nature of CBC mode). ChaCha20-Poly1305 is much faster.

Again, cookie-rs's current crypto is not insecure, just slow.

Supporting read only SignedJar?

Current signed method requires &mut self even if you need only reading the value. And I guess PrivateJar has the same problem.
Are there any chance to support read only SignedJar that can be obtained from non-mutable self and serves only get method?

Can the lifetime of &self and 'c teased apart in the signatures of some methods?

Let's say I only use Cookie temporarily to parse a cookie string I received in an HTTP header. In that case, I have the underlying string already allocated, and call parse on that to get a Cookie<'c> that has the lifetime 'c that is at maximum as long as the lifetime of the allocated string.

However, I'm only interested about the value of the cookie, not anything else, so I want to call .value(), get a &str to the value and discard the cookie struct as a temporary.

Currently this crate doesn't seem to support an usage like that. The problem is that .value() returns a &str that has the same lifetime than &self that was passed to the .value() method. If the returned &str had the same lifetime than the underlying allocated string, I could discard the cookie struct, but now I can't.

Is it possible to change that .value() returns &'c str? instead of &str?

Minimum supported Rust version?

What is the current MSRV for Cookie, and the threshold for upping it? As the revamped time crate is nearing release, it looks doable to update the dependency here. However, the MSRV for that is 1.40.

Both of these would changes would necessarily bump the MSRV (and necessitate a 0.13 release), though #[non_exhaustive] would be useful elsewhere as well.

Basically, I'd like to make changes similar to those I made for Rocket (which were well-received!). I'm just curious if bumping the MSRV is allowed, and by how much.

`Cookie` default value for `path` should be `None`, not `Some("/")`

The current default value for the path field for Cookie is Some("/"). I'm using this crate from a user agent perspective, and per IETF RFC 6265 Section 5.1.4, a user agent should set the path based on the request-uri if it is not set via the Path attribute; e.g. should be "/foo/bar" for a cookie resulting from a request to "http://example.com/foo/bar/" if no Path attribute is included. With the current behavior, it is impossible for client code to distinguish if the parsed cookie contained no Path attribute, or "; Path=/", and as such cannot know when to set it from the request-uri.

Why the percent-decoding on key & value?

I hit a problem with cookie-rs as used by Servo.
A full and unnecessary long explanation is online.

It comes down to this: cookie-rs percent-decodes key and value when parsing and stores them as Strings.
Servo uses these without modification to send back as a HTTP header.

This breaks if the cookie is not to be interpreted as a percent-encoded value (e.g. having newlines %0A or things that make it invalid UTF-8: %EE).
The actual decoding dates back to last year.
It's undocumented and suprising IMO.

Any insights on why it was done this way?

P.S.: Also on Display only the value gets re-encoded, the key is used as-is, which is even more surprising.

A CookieJar cannot be shared between threads, even with a Mutex

use std::sync::{Arc, Mutex};
use std::thread;

extern crate cookie;
use cookie::{Cookie, CookieJar};

fn main() {
    let m = Arc::new(Mutex::new(CookieJar::new(b"f8f9eaf1ecdedff5e5b749c58115441e")));

    thread::spawn(move || {
      m
    });
}

This fails to compile with the following error message:

src/main.rs:10:5: 10:18 error: the trait `core::marker::Sync` is not implemented for the type `core::cell::UnsafeCell<std::collections::hash::map::HashMap<collections::string::String, cookie::Cookie>>` [E0277]
src/main.rs:10     thread::spawn(move || {
                   ^~~~~~~~~~~~~
src/main.rs:10:5: 10:18 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:10:5: 10:18 note: `core::cell::UnsafeCell<std::collections::hash::map::HashMap<collections::string::String, cookie::Cookie>>` cannot be shared between threads safely
src/main.rs:10     thread::spawn(move || {
                   ^~~~~~~~~~~~~
src/main.rs:10:5: 10:18 error: the trait `core::marker::Sync` is not implemented for the type `core::cell::UnsafeCell<std::collections::hash::set::HashSet<collections::string::String>>` [E0277]
src/main.rs:10     thread::spawn(move || {
                   ^~~~~~~~~~~~~
src/main.rs:10:5: 10:18 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:10:5: 10:18 note: `core::cell::UnsafeCell<std::collections::hash::set::HashSet<collections::string::String>>` cannot be shared between threads safely
src/main.rs:10     thread::spawn(move || {
                   ^~~~~~~~~~~~~
src/main.rs:10:5: 10:18 error: the trait `core::marker::Sync` is not implemented for the type `core::cell::UnsafeCell<usize>` [E0277]
src/main.rs:10     thread::spawn(move || {
                   ^~~~~~~~~~~~~
src/main.rs:10:5: 10:18 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:10:5: 10:18 note: `core::cell::UnsafeCell<usize>` cannot be shared between threads safely
src/main.rs:10     thread::spawn(move || {

I've been looking for a consumer-side solution for over an hour now, but couldn't find one. Is the problem with CookieJar itself?

Options for `secure` feature with a different crypto library?

Hello! What do you think about adding some indirection over the ring APIs used in this crate and optionally allowing users to choose openssl/boring/mundane/etc for their crypto implementation? It would obviously have (potentially severe?) security and ergonomics tradeoffs to consider, but having a more stable option would be very nice given the recent mass-yanking of ring versions.

rust-url is at 0.2.2

So depending on rust-url and cookie-rs at the same time causes conflicts, unless I force the version back down to 0.1.0. Is it necessary to include the version here when depending on the git version?

delta to return a Vec<Cookie>

I'd love to add Jar support into hyper. At the moment, to support the delta function, I get back a vector or strings that I need to slice the header label off, and then write to a stream.

Discussion: Could parsing and signing be split into two separate crates?

Can I open a discussion on potentially splitting this into two separate crates, one for cookie jars + signing, and one for general purpose cookie parsing?

At it is right now this crate does two quite different things:

  • Parse cookies from strings into useful structs and vice-versa - general utility useful to almost any web application
  • Manage cryptographically signed cookies - much more specific and opinionated feature, not useful in all web applications

Even if un-used, the second feature existing comes with a price - Hyper no longer imports this crate due to the optional dependency on openssl. Upshot: it's now no longer possible to parse cookies out of the box in Iron.

If the features were split into two different crates then crates like Hyper (and anyone else only wanting to parse cookies, not sign them) could continue using the nice API here for that, and people who still want both would be unaffected (there's no reason the public API of this crate would need to change at all).

time crate dependency

This might be a stupid question, but does the time crate offer anything in addition to std::time? Replacing it would be a breaking change, but is there more to it?

Why is the leading full stop in domain omitted?

// parse.rs:160
let domain = match v.starts_with('.') {
    true => &v[1..],
    false => v,
};

What is the purpose of this? I believe that the leading full stop is not meaningless as cookies for .example.com are visible to sub.example.com whereas the ones for example.com are not.

What is the expected way to clone a Cookie?

How to clone a Cookie to a specific lifetime? For example,

struct NaiveCookieJar<'a> {
    data: HashMap<(String, String), Cookie<'a>>,
}

impl<'a> NaiveCookieJar<'a> {
    fn add(&mut self, domain: &str, name: &str, cookie: &Cookie) -> bool {
        /* this works for static 'a
        self.data
            .insert((String::from(domain), String::from(name)),
                    cookie.clone().into_owned())
            .is_some()
        */
        self.data.insert((String::from(domain), String::from(name)), cookie.clone()).is_some()
    }
}

This code resulted in error: E0495: cannot infer an appropriate lifetime for lifetime parameter 'c due to conflicting requirements

It seems that cookie.clone() is not working because Cookie holds a Cow<'a, str>. Then what is the proper way to do this?

Rename jar to session or something else?

I was talking to @seanmonstar in #hyper earlier tonight, and he said that he wasn't sure if cookie::jar was named correctly:

I think the jar in cookie is not what we typically think of for a jar usually a jar is what the user agent has, but the cookie crate's version is more like what many would think of as a session
...
usually, a session is when a server receives a request, looks in its cookie headers for some state, and then the server possibly updates that session, which results in probably new Set-Cookie headers being sent
its only for a single user, and their interaction with that specific server
whereas a jar, in user agents, holds all the cookies the browser has seen for that user, for any website

If it's the case that "jar" is mainly used for user agents, but the current module is designed for servers, should we consider renaming this module to something else?

Release with updated ring dependency

This is a follow-on from taskcluster/rust-hawk#14, where @eoger mentions that old versions of ring are regularly yanked. In particular, this is preventing me from using the latest rust-hawk with rocket:

error: failed to select a version for `ring`.
    ... required by package `hawk v1.0.5`
    ... which is depended on by `rocket-play v0.1.0 (/home/dustin/tmp/rocket-play)`
versions that meet the requirements `^0.14.5` are: 0.14.6, 0.14.5

the package `ring` links to the native library `ring-asm`, but it conflicts with a previous package which links to `ring-asm` as well:
package `ring v0.13.5`
    ... which is depended on by `cookie v0.11.0`
    ... which is depended on by `rocket_http v0.4.0`
    ... which is depended on by `rocket v0.4.0`
    ... which is depended on by `rocket-play v0.1.0 (/home/dustin/tmp/rocket-play)`

I see that ring is already upgraded in master, but not released. Would you consider making a release?

Incorrectly parse "secure" attributes from cookies

From http://tools.ietf.org/html/rfc6265#section-5.2 the secure attribute may have a value (which must be ignored).

This means that a cookie like foo=bar ;HttpOnly; Secure=aaaa should set the secure flag of cookie to true, which is not the case right now.

I catched this bug by running the cookie test suite from https://github.com/abarth/http-state (see tests test_attribute000[4578]) which is focused on the secure flag. But the same goes for other attributes like httponly.

I will propose a fix soon.

Remove cookies are missing Path and Domain

When a cookie is removed from the Jar, it only records the cookie's name. So when the Set-Cookie header is generated to clear the cookie, the header does not have the Path or Domain parameters, even if the original cookie had them. This is a problem because the new Set-Cookie header only overwrites the previous cookie if the Path and Domain parameters match.

Encrypted Cookies

Hello @alexcrichton, what do you think about implementing an encrypted cookies support? It is quite useful for some cases, e.g. storing user sessions on the client side.

Will it be hard to implement? Probably I can do it myself if you will agreed to add such functionality.

Raw (bytes) percent encoded values

Some frameworks puts control characters into cookies. In my case, Revel puts NUL in cookies percent encoded.

The current API doesn't allow straight handling of this (I need to go through percent_encoding directly).

A formatter for using with the Cookie header

The current cookie.fmt() function outputs a cookie useful for the Set-Cookie header, but not the Cookie header. I've settled to just doing write!(f, "{}={}", cookie.name, cookie.value) in hyper, but perhaps that should live in this repo?

How can I unset a path?

It appears it's possible to set the path but is it possible to unset it once it's set? Passing "" doesn't help..

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.