From 7768bc1fdb4bdf2b44ba09e2b814c0e7c4dcc3ac Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 18 Nov 2016 22:20:29 +0000 Subject: [PATCH] Add MD5DigestStream and test --- lib/crypto/MD5Digest.h | 115 ++++++++++++++++++++++++++++- test/httpserver/testhttpserver.cpp | 11 +++ 2 files changed, 123 insertions(+), 3 deletions(-) diff --git a/lib/crypto/MD5Digest.h b/lib/crypto/MD5Digest.h index 1be01ea93..a83ffb002 100644 --- a/lib/crypto/MD5Digest.h +++ b/lib/crypto/MD5Digest.h @@ -21,7 +21,7 @@ // Created: 8/12/03 // // -------------------------------------------------------------------------- -class MD5Digest +class MD5Digest { public: MD5Digest(); @@ -45,13 +45,122 @@ class MD5Digest }; int CopyDigestTo(uint8_t *to); - bool DigestMatches(uint8_t *pCompareWith) const; private: - MD5_CTX md5; + MD5_CTX md5; uint8_t mDigest[MD5_DIGEST_LENGTH]; }; +class MD5DigestStream : public IOStream +{ +private: + MD5Digest mDigest; + MD5DigestStream(const MD5DigestStream &rToCopy); /* forbidden */ + MD5DigestStream& operator=(const MD5DigestStream &rToCopy); /* forbidden */ + bool mClosed; + +public: + MD5DigestStream() + : mClosed(false) + { } + + virtual int Read(void *pBuffer, int NBytes, + int Timeout = IOStream::TimeOutInfinite) + { + THROW_EXCEPTION(CommonException, NotSupported); + } + virtual pos_type BytesLeftToRead() + { + THROW_EXCEPTION(CommonException, NotSupported); + } + virtual void Write(const void *pBuffer, int NBytes, + int Timeout = IOStream::TimeOutInfinite) + { + mDigest.Add(pBuffer, NBytes); + } + virtual void Write(const std::string& rBuffer, + int Timeout = IOStream::TimeOutInfinite) + { + mDigest.Add(rBuffer); + } + virtual void WriteAllBuffered(int Timeout = IOStream::TimeOutInfinite) { } + virtual pos_type GetPosition() const + { + THROW_EXCEPTION(CommonException, NotSupported); + } + virtual void Seek(pos_type Offset, int SeekType) + { + THROW_EXCEPTION(CommonException, NotSupported); + } + virtual void Close() + { + mDigest.Finish(); + mClosed = true; + } + + // Has all data that can be read been read? + virtual bool StreamDataLeft() + { + THROW_EXCEPTION(CommonException, NotSupported); + } + // Has the stream been closed (writing not possible) + virtual bool StreamClosed() + { + return mClosed; + } + + // Utility functions + bool ReadFullBuffer(void *pBuffer, int NBytes, int *pNBytesRead, + int Timeout = IOStream::TimeOutInfinite) + { + THROW_EXCEPTION(CommonException, NotSupported); + } + IOStream::pos_type CopyStreamTo(IOStream &rCopyTo, + int Timeout = IOStream::TimeOutInfinite, int BufferSize = 1024) + { + THROW_EXCEPTION(CommonException, NotSupported); + } + void Flush(int Timeout = IOStream::TimeOutInfinite) + { } + static int ConvertSeekTypeToOSWhence(int SeekType) + { + THROW_EXCEPTION(CommonException, NotSupported); + } + virtual std::string ToString() const + { + return "MD5DigestStream"; + } + + std::string DigestAsString() + { + // You can only get a digest when the stream has been closed, because this + // finalises the underlying MD5Digest object. + ASSERT(mClosed); + return mDigest.DigestAsString(); + } + uint8_t *DigestAsData(int *pLength = 0) + { + // You can only get a digest when the stream has been closed, because this + // finalises the underlying MD5Digest object. + ASSERT(mClosed); + return mDigest.DigestAsData(pLength); + } + int CopyDigestTo(uint8_t *to) + { + // You can only get a digest when the stream has been closed, because this + // finalises the underlying MD5Digest object. + ASSERT(mClosed); + return mDigest.CopyDigestTo(to); + } + bool DigestMatches(uint8_t *pCompareWith) const + { + // You can only get a digest when the stream has been closed, because this + // finalises the underlying MD5Digest object. + ASSERT(mClosed); + return mDigest.DigestMatches(pCompareWith); + } +}; + #endif // MD5DIGEST_H diff --git a/test/httpserver/testhttpserver.cpp b/test/httpserver/testhttpserver.cpp index 7bdfaf693..335ccd3ae 100644 --- a/test/httpserver/testhttpserver.cpp +++ b/test/httpserver/testhttpserver.cpp @@ -27,6 +27,7 @@ #include "HTTPServer.h" #include "HTTPTest.h" #include "IOStreamGetLine.h" +#include "MD5Digest.h" #include "S3Client.h" #include "S3Simulator.h" #include "ServerControl.h" @@ -237,6 +238,16 @@ bool test_httpserver() { SETUP(); + { + FileStream fs("testfiles/dsfdsfs98.fd"); + MD5DigestStream digester; + fs.CopyStreamTo(digester); + fs.Seek(0, IOStream::SeekType_Absolute); + digester.Close(); + std::string digest = digester.DigestAsString(); + TEST_EQUAL("dc3b8c5e57e71d31a0a9d7cbeee2e011", digest); + } + // Test that HTTPRequest can be written to and read from a stream. { HTTPRequest request(HTTPRequest::Method_PUT, "/newfile");