mirror of https://github.com/lukechilds/node.git
Browse Source
This change shouldn't have landed in the stable branch. It's a feature, not a bug fix. This reverts commitv0.10.4-release58f93ffc4a
. This reverts commit8c8ebe49b6
. This reverts commitba0f7b8066
. This reverts commit21f3c5c367
.
Ben Noordhuis
12 years ago
4 changed files with 5 additions and 421 deletions
@ -1,321 +0,0 @@ |
|||||
// Copyright Joyent, Inc. and other Node contributors.
|
|
||||
//
|
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||
// copy of this software and associated documentation files (the
|
|
||||
// "Software"), to deal in the Software without restriction, including
|
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
|
||||
// following conditions:
|
|
||||
//
|
|
||||
// The above copyright notice and this permission notice shall be included
|
|
||||
// in all copies or substantial portions of the Software.
|
|
||||
//
|
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||
|
|
||||
#include "node_crypto_bio.h" |
|
||||
#include "openssl/bio.h" |
|
||||
#include <string.h> |
|
||||
|
|
||||
namespace node { |
|
||||
|
|
||||
BIO_METHOD NodeBIO::method_ = { |
|
||||
BIO_TYPE_MEM, |
|
||||
"node.js SSL buffer", |
|
||||
NodeBIO::Write, |
|
||||
NodeBIO::Read, |
|
||||
NodeBIO::Puts, |
|
||||
NodeBIO::Gets, |
|
||||
NodeBIO::Ctrl, |
|
||||
NodeBIO::New, |
|
||||
NodeBIO::Free, |
|
||||
NULL |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
int NodeBIO::New(BIO* bio) { |
|
||||
bio->ptr = new NodeBIO(); |
|
||||
|
|
||||
// XXX Why am I doing it?!
|
|
||||
bio->shutdown = 1; |
|
||||
bio->init = 1; |
|
||||
bio->num = -1; |
|
||||
|
|
||||
return 1; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
int NodeBIO::Free(BIO* bio) { |
|
||||
if (bio == NULL) return 0; |
|
||||
|
|
||||
if (bio->shutdown) { |
|
||||
if (bio->init && bio->ptr != NULL) { |
|
||||
delete FromBIO(bio); |
|
||||
bio->ptr = NULL; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return 1; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
int NodeBIO::Read(BIO* bio, char* out, int len) { |
|
||||
int bytes; |
|
||||
BIO_clear_retry_flags(bio); |
|
||||
|
|
||||
bytes = FromBIO(bio)->Read(out, len); |
|
||||
|
|
||||
if (bytes == 0) { |
|
||||
bytes = bio->num; |
|
||||
if (bytes != 0) { |
|
||||
BIO_set_retry_read(bio); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return bytes; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
int NodeBIO::Write(BIO* bio, const char* data, int len) { |
|
||||
BIO_clear_retry_flags(bio); |
|
||||
|
|
||||
FromBIO(bio)->Write(data, len); |
|
||||
|
|
||||
return len; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
int NodeBIO::Puts(BIO* bio, const char* str) { |
|
||||
return Write(bio, str, strlen(str)); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
int NodeBIO::Gets(BIO* bio, char* out, int size) { |
|
||||
NodeBIO* nbio = FromBIO(bio); |
|
||||
|
|
||||
if (nbio->Length() == 0) |
|
||||
return 0; |
|
||||
|
|
||||
int i = nbio->IndexOf('\n', size); |
|
||||
|
|
||||
// Include '\n'
|
|
||||
if (i < size) i++; |
|
||||
|
|
||||
// Shift `i` a bit to NULL-terminate string later
|
|
||||
if (size == i) i--; |
|
||||
|
|
||||
// Flush read data
|
|
||||
nbio->Read(out, i); |
|
||||
|
|
||||
out[i] = 0; |
|
||||
|
|
||||
return i; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
long NodeBIO::Ctrl(BIO* bio, int cmd, long num, void* ptr) { |
|
||||
NodeBIO* nbio; |
|
||||
long ret; |
|
||||
|
|
||||
nbio = FromBIO(bio); |
|
||||
ret = 1; |
|
||||
|
|
||||
switch (cmd) { |
|
||||
case BIO_CTRL_RESET: |
|
||||
nbio->Reset(); |
|
||||
break; |
|
||||
case BIO_CTRL_EOF: |
|
||||
ret = nbio->Length() == 0; |
|
||||
break; |
|
||||
case BIO_C_SET_BUF_MEM_EOF_RETURN: |
|
||||
bio->num = num; |
|
||||
break; |
|
||||
case BIO_CTRL_INFO: |
|
||||
ret = nbio->Length(); |
|
||||
if (ptr != NULL) |
|
||||
*reinterpret_cast<void**>(ptr) = NULL; |
|
||||
break; |
|
||||
case BIO_C_SET_BUF_MEM: |
|
||||
assert(0 && "Can't use SET_BUF_MEM_PTR with NodeBIO"); |
|
||||
abort(); |
|
||||
break; |
|
||||
case BIO_C_GET_BUF_MEM_PTR: |
|
||||
assert(0 && "Can't use GET_BUF_MEM_PTR with NodeBIO"); |
|
||||
ret = 0; |
|
||||
break; |
|
||||
case BIO_CTRL_GET_CLOSE: |
|
||||
ret = bio->shutdown; |
|
||||
break; |
|
||||
case BIO_CTRL_SET_CLOSE: |
|
||||
bio->shutdown = num; |
|
||||
break; |
|
||||
case BIO_CTRL_WPENDING: |
|
||||
ret = 0; |
|
||||
break; |
|
||||
case BIO_CTRL_PENDING: |
|
||||
ret = nbio->Length(); |
|
||||
break; |
|
||||
case BIO_CTRL_DUP: |
|
||||
case BIO_CTRL_FLUSH: |
|
||||
ret = 1; |
|
||||
break; |
|
||||
case BIO_CTRL_PUSH: |
|
||||
case BIO_CTRL_POP: |
|
||||
default: |
|
||||
ret = 0; |
|
||||
break; |
|
||||
} |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
size_t NodeBIO::Read(char* out, size_t size) { |
|
||||
size_t bytes_read = 0; |
|
||||
size_t expected = Length() > size ? size : Length(); |
|
||||
size_t offset = 0; |
|
||||
size_t left = size; |
|
||||
|
|
||||
while (bytes_read < expected) { |
|
||||
assert(read_head_->read_pos_ <= read_head_->write_pos_); |
|
||||
size_t avail = read_head_->write_pos_ - read_head_->read_pos_; |
|
||||
if (avail > left) |
|
||||
avail = left; |
|
||||
|
|
||||
// Copy data
|
|
||||
if (out != NULL) |
|
||||
memcpy(out + offset, read_head_->data_ + read_head_->read_pos_, avail); |
|
||||
read_head_->read_pos_ += avail; |
|
||||
|
|
||||
// Move pointers
|
|
||||
bytes_read += avail; |
|
||||
offset += avail; |
|
||||
left -= avail; |
|
||||
|
|
||||
// Move to next buffer
|
|
||||
if (read_head_->read_pos_ == read_head_->write_pos_) { |
|
||||
read_head_->read_pos_ = 0; |
|
||||
read_head_->write_pos_ = 0; |
|
||||
|
|
||||
// But not get beyond write_head_
|
|
||||
if (bytes_read != expected) |
|
||||
read_head_ = read_head_->next_; |
|
||||
} |
|
||||
} |
|
||||
assert(expected == bytes_read); |
|
||||
length_ -= bytes_read; |
|
||||
|
|
||||
return bytes_read; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
size_t NodeBIO::IndexOf(char delim, size_t limit) { |
|
||||
size_t bytes_read = 0; |
|
||||
size_t max = Length() > limit ? limit : Length(); |
|
||||
size_t left = limit; |
|
||||
Buffer* current = read_head_; |
|
||||
|
|
||||
while (bytes_read < max) { |
|
||||
assert(current->read_pos_ <= current->write_pos_); |
|
||||
size_t avail = current->write_pos_ - current->read_pos_; |
|
||||
if (avail > left) |
|
||||
avail = left; |
|
||||
|
|
||||
// Walk through data
|
|
||||
char* tmp = current->data_ + current->read_pos_; |
|
||||
size_t off = 0; |
|
||||
while (off < avail && *tmp != delim) { |
|
||||
off++; |
|
||||
tmp++; |
|
||||
} |
|
||||
|
|
||||
// Move pointers
|
|
||||
bytes_read += off; |
|
||||
left -= off; |
|
||||
|
|
||||
// Found `delim`
|
|
||||
if (off != avail) { |
|
||||
return bytes_read; |
|
||||
} |
|
||||
|
|
||||
// Move to next buffer
|
|
||||
if (current->read_pos_ + avail == kBufferLength) { |
|
||||
current = current->next_; |
|
||||
} |
|
||||
} |
|
||||
assert(max == bytes_read); |
|
||||
|
|
||||
return max; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
void NodeBIO::Write(const char* data, size_t size) { |
|
||||
size_t offset = 0; |
|
||||
size_t left = size; |
|
||||
while (left > 0) { |
|
||||
size_t to_write = left; |
|
||||
assert(write_head_->write_pos_ <= kBufferLength); |
|
||||
size_t avail = kBufferLength - write_head_->write_pos_; |
|
||||
|
|
||||
if (to_write > avail) |
|
||||
to_write = avail; |
|
||||
|
|
||||
// Copy data
|
|
||||
memcpy(write_head_->data_ + write_head_->write_pos_, |
|
||||
data + offset, |
|
||||
to_write); |
|
||||
|
|
||||
// Move pointers
|
|
||||
left -= to_write; |
|
||||
offset += to_write; |
|
||||
length_ += to_write; |
|
||||
write_head_->write_pos_ += to_write; |
|
||||
assert(write_head_->write_pos_ <= kBufferLength); |
|
||||
|
|
||||
// Go to next buffer if there still are some bytes to write
|
|
||||
if (left != 0) { |
|
||||
if (write_head_->write_pos_ == kBufferLength) { |
|
||||
Buffer* next = new Buffer(); |
|
||||
next->next_ = write_head_->next_; |
|
||||
write_head_->next_ = next; |
|
||||
} |
|
||||
write_head_ = write_head_->next_; |
|
||||
} |
|
||||
} |
|
||||
assert(left == 0); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
void NodeBIO::Reset() { |
|
||||
while (read_head_->read_pos_ != read_head_->write_pos_) { |
|
||||
assert(read_head_->write_pos_ > read_head_->read_pos_); |
|
||||
|
|
||||
length_ -= read_head_->write_pos_ - read_head_->read_pos_; |
|
||||
read_head_->write_pos_ = 0; |
|
||||
read_head_->read_pos_ = 0; |
|
||||
|
|
||||
read_head_ = read_head_->next_; |
|
||||
} |
|
||||
write_head_ = read_head_; |
|
||||
assert(length_ == 0); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
NodeBIO::~NodeBIO() { |
|
||||
Buffer* current = head_.next_; |
|
||||
while (current != &head_) { |
|
||||
Buffer* next = current->next_; |
|
||||
delete current; |
|
||||
current = next; |
|
||||
} |
|
||||
|
|
||||
read_head_ = NULL; |
|
||||
write_head_ = NULL; |
|
||||
} |
|
||||
|
|
||||
} // namespace node
|
|
@ -1,93 +0,0 @@ |
|||||
// Copyright Joyent, Inc. and other Node contributors.
|
|
||||
//
|
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||
// copy of this software and associated documentation files (the
|
|
||||
// "Software"), to deal in the Software without restriction, including
|
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
|
||||
// following conditions:
|
|
||||
//
|
|
||||
// The above copyright notice and this permission notice shall be included
|
|
||||
// in all copies or substantial portions of the Software.
|
|
||||
//
|
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||
|
|
||||
#include "openssl/bio.h" |
|
||||
#include <assert.h> |
|
||||
|
|
||||
namespace node { |
|
||||
|
|
||||
class NodeBIO { |
|
||||
public: |
|
||||
static inline BIO_METHOD* GetMethod() { |
|
||||
return &method_; |
|
||||
} |
|
||||
|
|
||||
static int New(BIO* bio); |
|
||||
static int Free(BIO* bio); |
|
||||
static int Read(BIO* bio, char* out, int len); |
|
||||
static int Write(BIO* bio, const char* data, int len); |
|
||||
static int Puts(BIO* bio, const char* str); |
|
||||
static int Gets(BIO* bio, char* out, int size); |
|
||||
static long Ctrl(BIO* bio, int cmd, long num, void* ptr); |
|
||||
|
|
||||
protected: |
|
||||
static const size_t kBufferLength = 16 * 1024; |
|
||||
|
|
||||
class Buffer { |
|
||||
public: |
|
||||
Buffer() : read_pos_(0), write_pos_(0), next_(NULL) { |
|
||||
} |
|
||||
|
|
||||
size_t read_pos_; |
|
||||
size_t write_pos_; |
|
||||
Buffer* next_; |
|
||||
char data_[kBufferLength]; |
|
||||
}; |
|
||||
|
|
||||
NodeBIO() : length_(0), read_head_(&head_), write_head_(&head_) { |
|
||||
// Loop head
|
|
||||
head_.next_ = &head_; |
|
||||
} |
|
||||
|
|
||||
~NodeBIO(); |
|
||||
|
|
||||
// Read `len` bytes maximum into `out`, return actual number of read bytes
|
|
||||
size_t Read(char* out, size_t size); |
|
||||
|
|
||||
// Find first appearance of `delim` in buffer or `limit` if `delim`
|
|
||||
// wasn't found.
|
|
||||
size_t IndexOf(char delim, size_t limit); |
|
||||
|
|
||||
// Discard all available data
|
|
||||
void Reset(); |
|
||||
|
|
||||
// Put `len` bytes from `data` into buffer
|
|
||||
void Write(const char* data, size_t size); |
|
||||
|
|
||||
// Return size of buffer in bytes
|
|
||||
size_t inline Length() { |
|
||||
return length_; |
|
||||
} |
|
||||
|
|
||||
static inline NodeBIO* FromBIO(BIO* bio) { |
|
||||
assert(bio->ptr != NULL); |
|
||||
return static_cast<NodeBIO*>(bio->ptr); |
|
||||
} |
|
||||
|
|
||||
size_t length_; |
|
||||
Buffer head_; |
|
||||
Buffer* read_head_; |
|
||||
Buffer* write_head_; |
|
||||
|
|
||||
static BIO_METHOD method_; |
|
||||
}; |
|
||||
|
|
||||
} // namespace node
|
|
Loading…
Reference in new issue