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

Add OpenSSL::DigestIO to wrap an IO while calculating a digest #4260

Merged
merged 2 commits into from Jun 2, 2017

Conversation

spalladino
Copy link
Contributor

Wraps an IO by calculating a specified digest on read and/or write operations

Example

require "openssl"

underlying_io = IO::Memory.new("foo")
io = OpenSSL::DigestIO.new(underlying_io, "SHA256")
buffer = Bytes.new(256)
io.read(buffer)
io.digest # => 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae

def read(slice : Bytes)
read_bytes = io.read(slice)
if @digest_on_read
digest_algorithm.update(Bytes.new(slice.to_unsafe, read_bytes, read_only: true))
Copy link
Contributor

Choose a reason for hiding this comment

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

The usual way to do this is slice[0, read_bytes] instead of using Bytes.new and to_unsafe.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. Fixed.

def initialize(@io : IO, @digest_algorithm : OpenSSL::Digest, *, @digest_on_read = true, @digest_on_write = true)
end

def initialize(@io : IO, algorithm : String, *, @digest_on_read = true, @digest_on_write = true)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure I see a usecase for hashing read and write to the same hash, and it could cause some confusion. Maybe it would be best to make this exclusive (read or write digest).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Neither do I. I've changed both flags in favour of an enum Read/Write.

getter digest_on_write : Bool

delegate close, closed?, flush, peek, tty?, rewind, to: @io
delegate digest, to: @digest_algorithm
Copy link
Contributor

Choose a reason for hiding this comment

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

What about hexdigest and base64digest ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added

@@ -0,0 +1,55 @@
require "./digest_base"

# Wraps an IO by calculating a specified digest on read and/or write operations
Copy link
Contributor

Choose a reason for hiding this comment

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

Docs mention and, whereas right now it's either read or write.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's amazing how fast docs can become outdated. Thanks for the attention to detail!

delegate digest, hexdigest, base64digest, to: @digest_algorithm

def initialize(@io : IO, @digest_algorithm : OpenSSL::Digest, *, @digest_on_read = true, @digest_on_write = true)
enum DigestMode
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe rename this as just Mode as the surrounding class gives context. Maybe also bring out the members to the class level, so you only have to reference OpenSSL::DigestIO::Read.

delegate digest, hexdigest, base64digest, to: @digest_algorithm

enum DigestMode
Read,
Copy link
Contributor

Choose a reason for hiding this comment

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

Why a comma here? (I think the formatter should remove this)

@RX14
Copy link
Contributor

RX14 commented Apr 9, 2017

Also, maybe fix the typo (s/:/::/) in the commit message?

@spalladino
Copy link
Contributor Author

@RX14 done and done!

@@ -0,0 +1,55 @@
require "./digest_base"

# Wraps an IO by calculating a specified digest on read or write operations
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing dot ending the sentence :)

io_deferred.cr Outdated
@@ -0,0 +1,175 @@
module IO
Copy link
Contributor

Choose a reason for hiding this comment

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

Debug leftovers (along with the binary)?

foo.cr Outdated
@@ -0,0 +1,5 @@
# puts "A"
Copy link
Contributor

Choose a reason for hiding this comment

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

Debug leftovers?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Certainly. Fixing now.

@RX14
Copy link
Contributor

RX14 commented Apr 10, 2017

This PR is going to be perfect after all these reviews haha

@spalladino spalladino changed the title Add OpenSSL:DigestIO to wrap an IO while calculating a digest Add OpenSSL::DigestIO to wrap an IO while calculating a digest Apr 10, 2017
# io.read(buffer)
# io.digest # => 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
# ```
#
Copy link
Contributor

Choose a reason for hiding this comment

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

Redundant empty comment line :)


def read(slice : Bytes)
read_bytes = io.read(slice)
if @mode == DigestMode::Read
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use @mode.read? Enum helper instead?

end

def write(slice : Bytes)
if @mode == DigestMode::Write
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use @mode.write? Enum helper instead?

Copy link
Contributor

@luislavena luislavena left a comment

Choose a reason for hiding this comment

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

I think the only remaining piece here is the documentation block (and a rebase against latest master)

😄

@@ -0,0 +1,54 @@
require "./digest_base"

# Wraps an IO by calculating a specified digest on read or write operations.
Copy link
Contributor

Choose a reason for hiding this comment

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

Please move the documentation block to the DigestIO class instead. This will avoid OpenSSL module receive the digest-related documentation.

@spalladino
Copy link
Contributor Author

Awesome! Will do that next week. I've fried my Mac's HD and are setting everything back up :-P

@spalladino
Copy link
Contributor Author

@luislavena done! Rebase can be done without conflicts as well.

@matiasgarciaisaia matiasgarciaisaia self-requested a review May 20, 2017 05:11
@mverzilli mverzilli merged commit 66ac243 into crystal-lang:master Jun 2, 2017
@mverzilli mverzilli added this to the Next milestone Jun 2, 2017
@spalladino
Copy link
Contributor Author

Thanks @mverzilli!

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

Successfully merging this pull request may close these issues.

None yet

6 participants