Delete unused code in httpbase and httpcommon.
Deleted features include HttpBase::GetDocumentStream(), and support for other operations than GET. Bug: webrtc:6424 Change-Id: Ib16537cd1db87de53150f8e9e30dd89778a20c2e Reviewed-on: https://webrtc-review.googlesource.com/84140 Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24102}
This commit is contained in:
parent
7f5175a455
commit
b4731ff9cb
@ -223,150 +223,12 @@ void HttpParser::complete(HttpError error) {
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// HttpBase::DocumentStream
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
class BlockingMemoryStream : public ExternalMemoryStream {
|
||||
public:
|
||||
BlockingMemoryStream(char* buffer, size_t size)
|
||||
: ExternalMemoryStream(buffer, size) {}
|
||||
|
||||
StreamResult DoReserve(size_t size, int* error) override {
|
||||
return (buffer_length_ >= size) ? SR_SUCCESS : SR_BLOCK;
|
||||
}
|
||||
};
|
||||
|
||||
class HttpBase::DocumentStream : public StreamInterface {
|
||||
public:
|
||||
DocumentStream(HttpBase* base) : base_(base), error_(HE_DEFAULT) {}
|
||||
|
||||
StreamState GetState() const override {
|
||||
if (nullptr == base_)
|
||||
return SS_CLOSED;
|
||||
if (HM_RECV == base_->mode_)
|
||||
return SS_OPEN;
|
||||
return SS_OPENING;
|
||||
}
|
||||
|
||||
StreamResult Read(void* buffer,
|
||||
size_t buffer_len,
|
||||
size_t* read,
|
||||
int* error) override {
|
||||
if (!base_) {
|
||||
if (error)
|
||||
*error = error_;
|
||||
return (HE_NONE == error_) ? SR_EOS : SR_ERROR;
|
||||
}
|
||||
|
||||
if (HM_RECV != base_->mode_) {
|
||||
return SR_BLOCK;
|
||||
}
|
||||
|
||||
// DoReceiveLoop writes http document data to the StreamInterface* document
|
||||
// member of HttpData. In this case, we want this data to be written
|
||||
// directly to our buffer. To accomplish this, we wrap our buffer with a
|
||||
// StreamInterface, and replace the existing document with our wrapper.
|
||||
// When the method returns, we restore the old document. Ideally, we would
|
||||
// pass our StreamInterface* to DoReceiveLoop, but due to the callbacks
|
||||
// of HttpParser, we would still need to store the pointer temporarily.
|
||||
std::unique_ptr<StreamInterface> stream(
|
||||
new BlockingMemoryStream(reinterpret_cast<char*>(buffer), buffer_len));
|
||||
|
||||
// Replace the existing document with our wrapped buffer.
|
||||
base_->data_->document.swap(stream);
|
||||
|
||||
// Pump the I/O loop. DoReceiveLoop is guaranteed not to attempt to
|
||||
// complete the I/O process, which means that our wrapper is not in danger
|
||||
// of being deleted. To ensure this, DoReceiveLoop returns true when it
|
||||
// wants complete to be called. We make sure to uninstall our wrapper
|
||||
// before calling complete().
|
||||
HttpError http_error;
|
||||
bool complete = base_->DoReceiveLoop(&http_error);
|
||||
|
||||
// Reinstall the original output document.
|
||||
base_->data_->document.swap(stream);
|
||||
|
||||
// If we reach the end of the receive stream, we disconnect our stream
|
||||
// adapter from the HttpBase, and further calls to read will either return
|
||||
// EOS or ERROR, appropriately. Finally, we call complete().
|
||||
StreamResult result = SR_BLOCK;
|
||||
if (complete) {
|
||||
HttpBase* base = Disconnect(http_error);
|
||||
if (error)
|
||||
*error = error_;
|
||||
result = (HE_NONE == error_) ? SR_EOS : SR_ERROR;
|
||||
base->complete(http_error);
|
||||
}
|
||||
|
||||
// Even if we are complete, if some data was read we must return SUCCESS.
|
||||
// Future Reads will return EOS or ERROR based on the error_ variable.
|
||||
size_t position;
|
||||
stream->GetPosition(&position);
|
||||
if (position > 0) {
|
||||
if (read)
|
||||
*read = position;
|
||||
result = SR_SUCCESS;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
StreamResult Write(const void* data,
|
||||
size_t data_len,
|
||||
size_t* written,
|
||||
int* error) override {
|
||||
if (error)
|
||||
*error = -1;
|
||||
return SR_ERROR;
|
||||
}
|
||||
|
||||
void Close() override {
|
||||
if (base_) {
|
||||
HttpBase* base = Disconnect(HE_NONE);
|
||||
if (HM_RECV == base->mode_ && base->http_stream_) {
|
||||
// Read I/O could have been stalled on the user of this DocumentStream,
|
||||
// so restart the I/O process now that we've removed ourselves.
|
||||
base->http_stream_->PostEvent(SE_READ, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GetAvailable(size_t* size) const override {
|
||||
if (!base_ || HM_RECV != base_->mode_)
|
||||
return false;
|
||||
size_t data_size = base_->GetDataRemaining();
|
||||
if (SIZE_UNKNOWN == data_size)
|
||||
return false;
|
||||
if (size)
|
||||
*size = data_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
HttpBase* Disconnect(HttpError error) {
|
||||
RTC_DCHECK(nullptr != base_);
|
||||
RTC_DCHECK(nullptr != base_->doc_stream_);
|
||||
HttpBase* base = base_;
|
||||
base_->doc_stream_ = nullptr;
|
||||
base_ = nullptr;
|
||||
error_ = error;
|
||||
return base;
|
||||
}
|
||||
|
||||
private:
|
||||
HttpBase* base_;
|
||||
HttpError error_;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// HttpBase
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
HttpBase::HttpBase()
|
||||
: mode_(HM_NONE),
|
||||
data_(nullptr),
|
||||
notify_(nullptr),
|
||||
http_stream_(nullptr),
|
||||
doc_stream_(nullptr) {}
|
||||
: mode_(HM_NONE), data_(nullptr), notify_(nullptr), http_stream_(nullptr) {}
|
||||
|
||||
HttpBase::~HttpBase() {
|
||||
RTC_DCHECK(HM_NONE == mode_);
|
||||
@ -451,11 +313,7 @@ void HttpBase::recv(HttpData* data) {
|
||||
ignore_data_ = chunk_data_ = false;
|
||||
|
||||
reset();
|
||||
if (doc_stream_) {
|
||||
doc_stream_->SignalEvent(doc_stream_, SE_OPEN | SE_READ, 0);
|
||||
} else {
|
||||
read_and_process_data();
|
||||
}
|
||||
read_and_process_data();
|
||||
}
|
||||
|
||||
void HttpBase::abort(HttpError err) {
|
||||
@ -467,13 +325,6 @@ void HttpBase::abort(HttpError err) {
|
||||
}
|
||||
}
|
||||
|
||||
StreamInterface* HttpBase::GetDocumentStream() {
|
||||
if (doc_stream_)
|
||||
return nullptr;
|
||||
doc_stream_ = new DocumentStream(this);
|
||||
return doc_stream_;
|
||||
}
|
||||
|
||||
HttpError HttpBase::HandleStreamClose(int error) {
|
||||
if (http_stream_ != nullptr) {
|
||||
http_stream_->Close();
|
||||
@ -730,13 +581,6 @@ void HttpBase::do_complete(HttpError err) {
|
||||
data_->document->SignalEvent.disconnect(this);
|
||||
}
|
||||
data_ = nullptr;
|
||||
if ((HM_RECV == mode) && doc_stream_) {
|
||||
RTC_DCHECK(HE_NONE !=
|
||||
err); // We should have Disconnected doc_stream_ already.
|
||||
DocumentStream* ds = doc_stream_;
|
||||
ds->Disconnect(err);
|
||||
ds->SignalEvent(ds, SE_CLOSE, err);
|
||||
}
|
||||
if (notify_) {
|
||||
notify_->onHttpComplete(mode, err);
|
||||
}
|
||||
@ -761,11 +605,7 @@ void HttpBase::OnHttpStreamEvent(StreamInterface* stream,
|
||||
}
|
||||
|
||||
if ((events & SE_READ) && (mode_ == HM_RECV)) {
|
||||
if (doc_stream_) {
|
||||
doc_stream_->SignalEvent(doc_stream_, SE_READ, 0);
|
||||
} else {
|
||||
read_and_process_data();
|
||||
}
|
||||
read_and_process_data();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -825,7 +665,6 @@ HttpParser::ProcessResult HttpBase::ProcessHeader(const char* name,
|
||||
HttpParser::ProcessResult HttpBase::ProcessHeaderComplete(bool chunked,
|
||||
size_t& data_size,
|
||||
HttpError* error) {
|
||||
StreamInterface* old_docstream = doc_stream_;
|
||||
if (notify_) {
|
||||
*error = notify_->onHttpHeaderComplete(chunked, data_size);
|
||||
// The request must not be aborted as a result of this callback.
|
||||
@ -837,10 +676,6 @@ HttpParser::ProcessResult HttpBase::ProcessHeaderComplete(bool chunked,
|
||||
if (HE_NONE != *error) {
|
||||
return PR_COMPLETE;
|
||||
}
|
||||
if (old_docstream != doc_stream_) {
|
||||
// Break out of Process loop, since our I/O model just changed.
|
||||
return PR_BLOCK;
|
||||
}
|
||||
return PR_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
@ -119,11 +119,6 @@ class HttpBase : private HttpParser, public sigslot::has_slots<> {
|
||||
void set_ignore_data(bool ignore) { ignore_data_ = ignore; }
|
||||
bool ignore_data() const { return ignore_data_; }
|
||||
|
||||
// Obtaining this stream puts HttpBase into stream mode until the stream
|
||||
// is closed. HttpBase can only expose one open stream interface at a time.
|
||||
// Further calls will return null.
|
||||
StreamInterface* GetDocumentStream();
|
||||
|
||||
protected:
|
||||
// Do cleanup when the http stream closes (error may be 0 for a clean
|
||||
// shutdown), and return the error code to signal.
|
||||
@ -180,7 +175,6 @@ class HttpBase : private HttpParser, public sigslot::has_slots<> {
|
||||
HttpData* data_;
|
||||
IHttpNotify* notify_;
|
||||
StreamInterface* http_stream_;
|
||||
DocumentStream* doc_stream_;
|
||||
char buffer_[kBufferSize];
|
||||
size_t len_;
|
||||
|
||||
|
||||
@ -34,16 +34,6 @@ const char* const kHttpEmptyResponse =
|
||||
"Proxy-Authorization: 42\r\n"
|
||||
"\r\n";
|
||||
|
||||
const char* const kHttpResponsePrefix =
|
||||
"HTTP/1.1 200\r\n"
|
||||
"Connection: Keep-Alive\r\n"
|
||||
"Content-Type: text/plain\r\n"
|
||||
"Proxy-Authorization: 42\r\n"
|
||||
"Transfer-Encoding: chunked\r\n"
|
||||
"\r\n"
|
||||
"8\r\n"
|
||||
"Goodbye!\r\n";
|
||||
|
||||
class HttpBaseTest : public testing::Test, public IHttpNotify {
|
||||
public:
|
||||
enum EventType { E_HEADER_COMPLETE, E_COMPLETE, E_CLOSED };
|
||||
@ -54,7 +44,7 @@ class HttpBaseTest : public testing::Test, public IHttpNotify {
|
||||
HttpMode mode;
|
||||
HttpError err;
|
||||
};
|
||||
HttpBaseTest() : mem(nullptr), obtain_stream(false), http_stream(nullptr) {}
|
||||
HttpBaseTest() : mem(nullptr), http_stream(nullptr) {}
|
||||
|
||||
void TearDown() override {
|
||||
delete http_stream;
|
||||
@ -66,9 +56,6 @@ class HttpBaseTest : public testing::Test, public IHttpNotify {
|
||||
RTC_LOG_F(LS_VERBOSE) << "chunked: " << chunked << " size: " << data_size;
|
||||
Event e = {E_HEADER_COMPLETE, chunked, data_size, HM_NONE, HE_NONE};
|
||||
events.push_back(e);
|
||||
if (obtain_stream) {
|
||||
ObtainDocumentStream();
|
||||
}
|
||||
return HE_NONE;
|
||||
}
|
||||
void onHttpComplete(HttpMode mode, HttpError err) override {
|
||||
@ -88,7 +75,6 @@ class HttpBaseTest : public testing::Test, public IHttpNotify {
|
||||
void VerifyDocumentContents(const char* expected_data,
|
||||
size_t expected_length = SIZE_UNKNOWN);
|
||||
|
||||
void ObtainDocumentStream();
|
||||
void VerifyDocumentStreamIsOpening();
|
||||
void VerifyDocumentStreamOpenEvent();
|
||||
void ReadDocumentStreamData(const char* expected_data);
|
||||
@ -108,8 +94,7 @@ class HttpBaseTest : public testing::Test, public IHttpNotify {
|
||||
webrtc::testing::StreamSource src;
|
||||
std::vector<Event> events;
|
||||
|
||||
// Document stream, and stream events
|
||||
bool obtain_stream;
|
||||
// Stream events
|
||||
StreamInterface* http_stream;
|
||||
webrtc::testing::StreamSink sink;
|
||||
};
|
||||
@ -184,15 +169,6 @@ void HttpBaseTest::VerifyDocumentContents(const char* expected_data,
|
||||
RTC_LOG_F(LS_VERBOSE) << "Exit";
|
||||
}
|
||||
|
||||
void HttpBaseTest::ObtainDocumentStream() {
|
||||
RTC_LOG_F(LS_VERBOSE) << "Enter";
|
||||
EXPECT_FALSE(http_stream);
|
||||
http_stream = base.GetDocumentStream();
|
||||
ASSERT_TRUE(nullptr != http_stream);
|
||||
sink.Monitor(http_stream);
|
||||
RTC_LOG_F(LS_VERBOSE) << "Exit";
|
||||
}
|
||||
|
||||
void HttpBaseTest::VerifyDocumentStreamIsOpening() {
|
||||
RTC_LOG_F(LS_VERBOSE) << "Enter";
|
||||
ASSERT_TRUE(nullptr != http_stream);
|
||||
@ -379,145 +355,4 @@ TEST_F(HttpBaseTest, SupportsReceiveViaDocumentPush) {
|
||||
VerifyDocumentContents("Goodbye!");
|
||||
}
|
||||
|
||||
TEST_F(HttpBaseTest, SupportsReceiveViaStreamPull) {
|
||||
// Switch to pull mode
|
||||
ObtainDocumentStream();
|
||||
VerifyDocumentStreamIsOpening();
|
||||
|
||||
// Queue response document
|
||||
SetupSource(kHttpResponse);
|
||||
VerifyDocumentStreamIsOpening();
|
||||
|
||||
// Begin receive
|
||||
base.recv(&data);
|
||||
|
||||
// Pull document data
|
||||
VerifyDocumentStreamOpenEvent();
|
||||
ReadDocumentStreamData("Goodbye!");
|
||||
VerifyDocumentStreamIsEOS();
|
||||
|
||||
// Document completed successfully
|
||||
VerifyHeaderComplete(2, false);
|
||||
VerifyTransferComplete(HM_RECV, HE_NONE);
|
||||
VerifyDocumentContents("");
|
||||
}
|
||||
|
||||
TEST_F(HttpBaseTest, DISABLED_AllowsCloseStreamBeforeDocumentIsComplete) {
|
||||
// TODO: Remove extra logging once test failure is understood
|
||||
LoggingSeverity old_sev = rtc::LogMessage::GetLogToDebug();
|
||||
rtc::LogMessage::LogToDebug(LS_VERBOSE);
|
||||
|
||||
// Switch to pull mode
|
||||
ObtainDocumentStream();
|
||||
VerifyDocumentStreamIsOpening();
|
||||
|
||||
// Queue response document
|
||||
SetupSource(kHttpResponse);
|
||||
VerifyDocumentStreamIsOpening();
|
||||
|
||||
// Begin receive
|
||||
base.recv(&data);
|
||||
|
||||
// Pull some of the data
|
||||
VerifyDocumentStreamOpenEvent();
|
||||
ReadDocumentStreamData("Goodb");
|
||||
|
||||
// We've seen the header by now
|
||||
VerifyHeaderComplete(1, false);
|
||||
|
||||
// Close the pull stream, this will transition back to push I/O.
|
||||
http_stream->Close();
|
||||
Thread::Current()->ProcessMessages(0);
|
||||
|
||||
// Remainder of document completed successfully
|
||||
VerifyTransferComplete(HM_RECV, HE_NONE);
|
||||
VerifyDocumentContents("ye!");
|
||||
|
||||
rtc::LogMessage::LogToDebug(old_sev);
|
||||
}
|
||||
|
||||
TEST_F(HttpBaseTest, AllowsGetDocumentStreamInResponseToHttpHeader) {
|
||||
// Queue response document
|
||||
SetupSource(kHttpResponse);
|
||||
|
||||
// Switch to pull mode in response to header arrival
|
||||
obtain_stream = true;
|
||||
|
||||
// Begin receive
|
||||
base.recv(&data);
|
||||
|
||||
// We've already seen the header, but not data has arrived
|
||||
VerifyHeaderComplete(1, false);
|
||||
VerifyDocumentContents("");
|
||||
|
||||
// Pull the document data
|
||||
ReadDocumentStreamData("Goodbye!");
|
||||
VerifyDocumentStreamIsEOS();
|
||||
|
||||
// Document completed successfully
|
||||
VerifyTransferComplete(HM_RECV, HE_NONE);
|
||||
VerifyDocumentContents("");
|
||||
}
|
||||
|
||||
TEST_F(HttpBaseTest, AllowsGetDocumentStreamWithEmptyDocumentBody) {
|
||||
// Queue empty response document
|
||||
SetupSource(kHttpEmptyResponse);
|
||||
|
||||
// Switch to pull mode in response to header arrival
|
||||
obtain_stream = true;
|
||||
|
||||
// Begin receive
|
||||
base.recv(&data);
|
||||
|
||||
// We've already seen the header, but not data has arrived
|
||||
VerifyHeaderComplete(1, true);
|
||||
VerifyDocumentContents("");
|
||||
|
||||
// The document is still open, until we attempt to read
|
||||
ASSERT_TRUE(nullptr != http_stream);
|
||||
EXPECT_EQ(SS_OPEN, http_stream->GetState());
|
||||
|
||||
// Attempt to read data, and discover EOS
|
||||
VerifyDocumentStreamIsEOS();
|
||||
|
||||
// Document completed successfully
|
||||
VerifyTransferComplete(HM_RECV, HE_NONE);
|
||||
VerifyDocumentContents("");
|
||||
}
|
||||
|
||||
TEST_F(HttpBaseTest, SignalsDocumentStreamCloseOnUnexpectedClose) {
|
||||
// Switch to pull mode
|
||||
ObtainDocumentStream();
|
||||
VerifyDocumentStreamIsOpening();
|
||||
|
||||
// Queue response document
|
||||
SetupSource(kHttpResponsePrefix);
|
||||
VerifyDocumentStreamIsOpening();
|
||||
|
||||
// Begin receive
|
||||
base.recv(&data);
|
||||
|
||||
// Pull document data
|
||||
VerifyDocumentStreamOpenEvent();
|
||||
ReadDocumentStreamData("Goodbye!");
|
||||
|
||||
// Simulate unexpected close
|
||||
src.SetState(SS_CLOSED);
|
||||
|
||||
// Observe error event on document stream
|
||||
EXPECT_EQ(webrtc::testing::SSE_ERROR, sink.Events(http_stream));
|
||||
|
||||
// Future reads give an error
|
||||
int error = 0;
|
||||
char buffer[5] = {0};
|
||||
EXPECT_EQ(SR_ERROR,
|
||||
http_stream->Read(buffer, sizeof(buffer), nullptr, &error));
|
||||
EXPECT_EQ(HE_DISCONNECTED, error);
|
||||
|
||||
// Document completed with error
|
||||
VerifyHeaderComplete(2, false);
|
||||
VerifyTransferComplete(HM_RECV, HE_DISCONNECTED);
|
||||
VerifyDocumentContents("");
|
||||
}
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
@ -169,10 +169,6 @@ struct Enum {
|
||||
static const char* kHttpVersions[HVER_LAST + 1] = {"1.0", "1.1", "Unknown"};
|
||||
ENUM(HttpVersion, kHttpVersions);
|
||||
|
||||
static const char* kHttpVerbs[HV_LAST + 1] = {"GET", "POST", "PUT",
|
||||
"DELETE", "CONNECT", "HEAD"};
|
||||
ENUM(HttpVerb, kHttpVerbs);
|
||||
|
||||
static const char* kHttpHeaders[HH_LAST + 1] = {
|
||||
"Age",
|
||||
"Cache-Control",
|
||||
@ -213,14 +209,6 @@ bool FromString(HttpVersion& version, const std::string& str) {
|
||||
return Enum<HttpVersion>::Parse(version, str);
|
||||
}
|
||||
|
||||
const char* ToString(HttpVerb verb) {
|
||||
return Enum<HttpVerb>::Name(verb);
|
||||
}
|
||||
|
||||
bool FromString(HttpVerb& verb, const std::string& str) {
|
||||
return Enum<HttpVerb>::Parse(verb, str);
|
||||
}
|
||||
|
||||
const char* ToString(HttpHeader header) {
|
||||
return Enum<HttpHeader>::Name(header);
|
||||
}
|
||||
@ -229,25 +217,6 @@ bool FromString(HttpHeader& header, const std::string& str) {
|
||||
return Enum<HttpHeader>::Parse(header, str);
|
||||
}
|
||||
|
||||
bool HttpCodeHasBody(uint32_t code) {
|
||||
return !HttpCodeIsInformational(code) && (code != HC_NO_CONTENT) &&
|
||||
(code != HC_NOT_MODIFIED);
|
||||
}
|
||||
|
||||
bool HttpCodeIsCacheable(uint32_t code) {
|
||||
switch (code) {
|
||||
case HC_OK:
|
||||
case HC_NON_AUTHORITATIVE:
|
||||
case HC_PARTIAL_CONTENT:
|
||||
case HC_MULTIPLE_CHOICES:
|
||||
case HC_MOVED_PERMANENTLY:
|
||||
case HC_GONE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool HttpHeaderIsEndToEnd(HttpHeader header) {
|
||||
switch (header) {
|
||||
case HH_CONNECTION:
|
||||
@ -494,10 +463,6 @@ void HttpData::clear(bool release_document) {
|
||||
}
|
||||
}
|
||||
|
||||
void HttpData::copy(const HttpData& src) {
|
||||
headers_ = src.headers_;
|
||||
}
|
||||
|
||||
void HttpData::changeHeader(const std::string& name,
|
||||
const std::string& value,
|
||||
HeaderCombine combine) {
|
||||
@ -572,21 +537,14 @@ void HttpData::setDocumentAndLength(StreamInterface* document) {
|
||||
//
|
||||
|
||||
void HttpRequestData::clear(bool release_document) {
|
||||
verb = HV_GET;
|
||||
path.clear();
|
||||
HttpData::clear(release_document);
|
||||
}
|
||||
|
||||
void HttpRequestData::copy(const HttpRequestData& src) {
|
||||
verb = src.verb;
|
||||
path = src.path;
|
||||
HttpData::copy(src);
|
||||
}
|
||||
|
||||
size_t HttpRequestData::formatLeader(char* buffer, size_t size) const {
|
||||
RTC_DCHECK(path.find(' ') == std::string::npos);
|
||||
return sprintfn(buffer, size, "%s %.*s HTTP/%s", ToString(verb), path.size(),
|
||||
path.data(), ToString(version));
|
||||
return sprintfn(buffer, size, "GET %.*s HTTP/%s", path.size(), path.data(),
|
||||
ToString(version));
|
||||
}
|
||||
|
||||
HttpError HttpRequestData::parseLeader(const char* line, size_t len) {
|
||||
@ -608,8 +566,7 @@ HttpError HttpRequestData::parseLeader(const char* line, size_t len) {
|
||||
} else {
|
||||
return HE_PROTOCOL;
|
||||
}
|
||||
std::string sverb(line, vend);
|
||||
if (!FromString(verb, sverb.c_str())) {
|
||||
if (vend != 3 || memcmp(line, "GET", 3)) {
|
||||
return HE_PROTOCOL; // !?! HC_METHOD_NOT_SUPPORTED?
|
||||
}
|
||||
path.assign(line + dstart, line + dend);
|
||||
@ -617,8 +574,6 @@ HttpError HttpRequestData::parseLeader(const char* line, size_t len) {
|
||||
}
|
||||
|
||||
bool HttpRequestData::getAbsoluteUri(std::string* uri) const {
|
||||
if (HV_CONNECT == verb)
|
||||
return false;
|
||||
Url<char> url(path);
|
||||
if (url.valid()) {
|
||||
uri->assign(path);
|
||||
@ -635,8 +590,6 @@ bool HttpRequestData::getAbsoluteUri(std::string* uri) const {
|
||||
|
||||
bool HttpRequestData::getRelativeUri(std::string* host,
|
||||
std::string* path) const {
|
||||
if (HV_CONNECT == verb)
|
||||
return false;
|
||||
Url<char> url(this->path);
|
||||
if (url.valid()) {
|
||||
host->assign(url.address());
|
||||
@ -659,34 +612,12 @@ void HttpResponseData::clear(bool release_document) {
|
||||
HttpData::clear(release_document);
|
||||
}
|
||||
|
||||
void HttpResponseData::copy(const HttpResponseData& src) {
|
||||
scode = src.scode;
|
||||
message = src.message;
|
||||
HttpData::copy(src);
|
||||
}
|
||||
|
||||
void HttpResponseData::set_success(uint32_t scode) {
|
||||
this->scode = scode;
|
||||
message.clear();
|
||||
setHeader(HH_CONTENT_LENGTH, "0", false);
|
||||
}
|
||||
|
||||
void HttpResponseData::set_success(const std::string& content_type,
|
||||
StreamInterface* document,
|
||||
uint32_t scode) {
|
||||
this->scode = scode;
|
||||
message.erase(message.begin(), message.end());
|
||||
setContent(content_type, document);
|
||||
}
|
||||
|
||||
void HttpResponseData::set_redirect(const std::string& location,
|
||||
uint32_t scode) {
|
||||
this->scode = scode;
|
||||
message.clear();
|
||||
setHeader(HH_LOCATION, location);
|
||||
setHeader(HH_CONTENT_LENGTH, "0", false);
|
||||
}
|
||||
|
||||
void HttpResponseData::set_error(uint32_t scode) {
|
||||
this->scode = scode;
|
||||
message.clear();
|
||||
|
||||
@ -31,41 +31,11 @@ class SocketAddress;
|
||||
|
||||
enum HttpCode {
|
||||
HC_OK = 200,
|
||||
HC_NON_AUTHORITATIVE = 203,
|
||||
HC_NO_CONTENT = 204,
|
||||
HC_PARTIAL_CONTENT = 206,
|
||||
|
||||
HC_MULTIPLE_CHOICES = 300,
|
||||
HC_MOVED_PERMANENTLY = 301,
|
||||
HC_FOUND = 302,
|
||||
HC_SEE_OTHER = 303,
|
||||
HC_NOT_MODIFIED = 304,
|
||||
HC_MOVED_TEMPORARILY = 307,
|
||||
|
||||
HC_BAD_REQUEST = 400,
|
||||
HC_UNAUTHORIZED = 401,
|
||||
HC_FORBIDDEN = 403,
|
||||
HC_NOT_FOUND = 404,
|
||||
HC_PROXY_AUTHENTICATION_REQUIRED = 407,
|
||||
HC_GONE = 410,
|
||||
|
||||
HC_INTERNAL_SERVER_ERROR = 500,
|
||||
HC_NOT_IMPLEMENTED = 501,
|
||||
HC_SERVICE_UNAVAILABLE = 503,
|
||||
};
|
||||
|
||||
enum HttpVersion { HVER_1_0, HVER_1_1, HVER_UNKNOWN, HVER_LAST = HVER_UNKNOWN };
|
||||
|
||||
enum HttpVerb {
|
||||
HV_GET,
|
||||
HV_POST,
|
||||
HV_PUT,
|
||||
HV_DELETE,
|
||||
HV_CONNECT,
|
||||
HV_HEAD,
|
||||
HV_LAST = HV_HEAD
|
||||
};
|
||||
|
||||
enum HttpError {
|
||||
HE_NONE,
|
||||
HE_PROTOCOL, // Received non-valid HTTP data
|
||||
@ -121,37 +91,12 @@ const uint16_t HTTP_SECURE_PORT = 443;
|
||||
// Utility Functions
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline HttpError mkerr(HttpError err, HttpError def_err = HE_DEFAULT) {
|
||||
return (err != HE_NONE) ? err : def_err;
|
||||
}
|
||||
|
||||
const char* ToString(HttpVersion version);
|
||||
bool FromString(HttpVersion& version, const std::string& str);
|
||||
|
||||
const char* ToString(HttpVerb verb);
|
||||
bool FromString(HttpVerb& verb, const std::string& str);
|
||||
|
||||
const char* ToString(HttpHeader header);
|
||||
bool FromString(HttpHeader& header, const std::string& str);
|
||||
|
||||
inline bool HttpCodeIsInformational(uint32_t code) {
|
||||
return ((code / 100) == 1);
|
||||
}
|
||||
inline bool HttpCodeIsSuccessful(uint32_t code) {
|
||||
return ((code / 100) == 2);
|
||||
}
|
||||
inline bool HttpCodeIsRedirection(uint32_t code) {
|
||||
return ((code / 100) == 3);
|
||||
}
|
||||
inline bool HttpCodeIsClientError(uint32_t code) {
|
||||
return ((code / 100) == 4);
|
||||
}
|
||||
inline bool HttpCodeIsServerError(uint32_t code) {
|
||||
return ((code / 100) == 5);
|
||||
}
|
||||
|
||||
bool HttpCodeHasBody(uint32_t code);
|
||||
bool HttpCodeIsCacheable(uint32_t code);
|
||||
bool HttpHeaderIsEndToEnd(HttpHeader header);
|
||||
bool HttpHeaderIsCollapsible(HttpHeader header);
|
||||
|
||||
@ -382,20 +327,17 @@ struct HttpData {
|
||||
protected:
|
||||
virtual ~HttpData();
|
||||
void clear(bool release_document);
|
||||
void copy(const HttpData& src);
|
||||
|
||||
private:
|
||||
HeaderMap headers_;
|
||||
};
|
||||
|
||||
struct HttpRequestData : public HttpData {
|
||||
HttpVerb verb;
|
||||
std::string path;
|
||||
|
||||
HttpRequestData() : verb(HV_GET) {}
|
||||
HttpRequestData() {}
|
||||
|
||||
void clear(bool release_document);
|
||||
void copy(const HttpRequestData& src);
|
||||
|
||||
size_t formatLeader(char* buffer, size_t size) const override;
|
||||
HttpError parseLeader(const char* line, size_t len) override;
|
||||
@ -410,15 +352,9 @@ struct HttpResponseData : public HttpData {
|
||||
|
||||
HttpResponseData() : scode(HC_INTERNAL_SERVER_ERROR) {}
|
||||
void clear(bool release_document);
|
||||
void copy(const HttpResponseData& src);
|
||||
|
||||
// Convenience methods
|
||||
void set_success(uint32_t scode = HC_OK);
|
||||
void set_success(const std::string& content_type,
|
||||
StreamInterface* document,
|
||||
uint32_t scode = HC_OK);
|
||||
void set_redirect(const std::string& location,
|
||||
uint32_t scode = HC_MOVED_TEMPORARILY);
|
||||
void set_error(uint32_t scode);
|
||||
|
||||
size_t formatLeader(char* buffer, size_t size) const override;
|
||||
|
||||
@ -552,22 +552,6 @@ StreamResult MemoryStream::DoReserve(size_t size, int* error) {
|
||||
return SR_ERROR;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExternalMemoryStream::ExternalMemoryStream() {}
|
||||
|
||||
ExternalMemoryStream::ExternalMemoryStream(void* data, size_t length) {
|
||||
SetData(data, length);
|
||||
}
|
||||
|
||||
ExternalMemoryStream::~ExternalMemoryStream() {}
|
||||
|
||||
void ExternalMemoryStream::SetData(void* data, size_t length) {
|
||||
data_length_ = buffer_length_ = length;
|
||||
buffer_ = static_cast<char*>(data);
|
||||
seek_position_ = 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// FifoBuffer
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -421,18 +421,6 @@ class MemoryStream : public MemoryStreamBase {
|
||||
StreamResult DoReserve(size_t size, int* error) override;
|
||||
};
|
||||
|
||||
// ExternalMemoryStream adapts an external memory buffer, so writes which would
|
||||
// extend past the end of the buffer will return end-of-stream.
|
||||
|
||||
class ExternalMemoryStream : public MemoryStreamBase {
|
||||
public:
|
||||
ExternalMemoryStream();
|
||||
ExternalMemoryStream(void* data, size_t length);
|
||||
~ExternalMemoryStream() override;
|
||||
|
||||
void SetData(void* data, size_t length);
|
||||
};
|
||||
|
||||
// FifoBuffer allows for efficient, thread-safe buffering of data between
|
||||
// writer and reader. As the data can wrap around the end of the buffer,
|
||||
// MemoryStreamBase can't help us here.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user