Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(headers): add Range header #560

Merged
merged 1 commit into from
Jun 16, 2015
Merged

Conversation

lame-nickname
Copy link
Contributor

There are 2 TODOs left in the code. I wasn't sure what is the best way to handle these cases and I'd like to hear your feedback on that.

What I also wasn't sure about, are the names of values inside the RangeSpec enum, as well as the name of enum itself. Maybe you'll be able to come up with better ones ;)

@seanmonstar
Copy link
Member

Woo, thanks! I'll look this over. Also pinging @pyfisch, since he's done a ton of work on the headers.

/// Each 'Range' header can contain one or more RangeSpecs.
/// Each RangeSpec defines a range of units to fetch
#[derive(PartialEq, Clone, Debug)]
pub enum RangeSpec {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder, would it work out nicely to use std::ops::{Range, RangeFrom, RangeTo}? This could allow usage like let ranges = vec![ 0..1, 30..40];

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if that makes sense. The thing is that Range and RangeFrom have their equivalent in the RangeSpec struct, but RangeTo doesn't. So we could implement Into<RangeSpec> for RangeTo and for Range, but that would leave out RangeFrom (and RangeSpec::Last), which IMO isn't very clean.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I hadn't read the Range spec before suggesting that. I didn't realize that bytes=-500 means the last 500 bytes, I assumed it means 0-500.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made the same assumption when I've started implementing it ;)

@lame-nickname
Copy link
Contributor Author

Ok, so in the new commit, I've included all your suggestions regarding iterators and unnecessary allocations.

I've also made some decisions regarding the TODOs:
1). I think it makes sense to allow Range without any ranges (empty vector). In that case it will be transmitted as "bytes=" and it will be up to a server do decide what to do with it.
2) Now instead of skipping bad ranges during parsing, we'll return an Err, which basically means that the whole Range header is invalid.

headers.set(Range {unit: RangeUnit::Bytes, ranges: vec![]});

assert_eq!(&headers.to_string(), "Range: bytes=\r\n");
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mind adding the bench_header! macro usage down here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@seanmonstar
Copy link
Member

This looks good to go. Thanks! Would you mind squashing into a single commit? The changelog only really needs to report 1 new feature: added the Range header.

type Err = ();

fn from_str(s: &str) -> Result<RangeSpec, ()> {
let mut parts = s.split("-");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should probably use splitn(2) here. Imagine a malformed RangeSpec like 200-300-foobar. It would pass as valid.

@pyfisch
Copy link
Contributor

pyfisch commented Jun 10, 2015

Sorry for the late comments, some are a bit nitpicky but they should help to archieve a higher conformance with the spec 😉

@lame-nickname
Copy link
Contributor Author

No worries. I'm glad you've reviewed the commits, as there were several things I've clearly missed reading the HTTP spec. Will do better next time! ;)

@GitCop
Copy link

GitCop commented Jun 15, 2015

Thanks for contributing! Unfortunately, I'm here to tell you there were the following style issues with your Pull Request:

  • Commit: 287dc39
    • Commits must be in the following format: %{type}(%{scope}): %{description}
  • Commit: 808ccdd
    • Commits must be in the following format: %{type}(%{scope}): %{description}

Guidelines are available at https://github.com/hyperium/hyper/blob/master/CONTRIBUTING.md


This message was auto-generated by https://gitcop.com

@lame-nickname
Copy link
Contributor Author

Ok guys, I've made the requested changes. I wouldn't be surprised if they were unidiomatic, so let me know if that's the case.

There are 2 open issues:

  • i.e. bytes=-1,-1,-1 or bytes=1-,1-. According to the spec, there should be only one range spec of {RangeSpec::AllFrom, RangeSpec::Last} and it should always be at the end of the range set. Currently, it's not enforced and it's up to the application code to check that.
  • i.e. bytes=1-100,abc,200-. Should we just drop the invalid range specs and mark the whole range as valid (as long as there is at least one valid range spec) or mark the range as invalid, if there is at least one invalid range spec? Currently, we do the former.

use header::{Header, HeaderFormat, RangeUnit};
use header::parsing::{from_one_raw_str, from_one_comma_delimited};

/// `Range` header, defined in [RFC7233](https://tools.ietf.org/html/rfc7233#section-3.1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice docs

@GitCop
Copy link

GitCop commented Jun 15, 2015

Thanks for contributing! Unfortunately, I'm here to tell you there were the following style issues with your Pull Request:

  • Commit: 287dc39
    • Commits must be in the following format: %{type}(%{scope}): %{description}
  • Commit: 808ccdd
    • Commits must be in the following format: %{type}(%{scope}): %{description}

Guidelines are available at https://github.com/hyperium/hyper/blob/master/CONTRIBUTING.md


This message was auto-generated by https://gitcop.com

1 similar comment
@GitCop
Copy link

GitCop commented Jun 15, 2015

Thanks for contributing! Unfortunately, I'm here to tell you there were the following style issues with your Pull Request:

  • Commit: 287dc39
    • Commits must be in the following format: %{type}(%{scope}): %{description}
  • Commit: 808ccdd
    • Commits must be in the following format: %{type}(%{scope}): %{description}

Guidelines are available at https://github.com/hyperium/hyper/blob/master/CONTRIBUTING.md


This message was auto-generated by https://gitcop.com

@pyfisch
Copy link
Contributor

pyfisch commented Jun 16, 2015

+1

seanmonstar added a commit that referenced this pull request Jun 16, 2015
feat(headers): add `Range` header
@seanmonstar seanmonstar merged commit 41823ca into hyperium:master Jun 16, 2015
@seanmonstar
Copy link
Member

Excellent work! Thanks for sticking with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants