From b1d3a71cf567dc7c27c7d08cf1e1747013d56159 Mon Sep 17 00:00:00 2001 From: ridethepig Date: Wed, 15 Feb 2023 10:09:56 +0000 Subject: [PATCH] lab0 ok --- apps/webget.cc | 14 +++++-- libsponge/byte_stream.cc | 54 +++++++++++++++++-------- libsponge/byte_stream.hh | 6 +++ libsponge/util/eventloop.hh | 11 +++--- writeups/lab0.md | 79 ++++++++++++++++++++++++++++++++++--- 5 files changed, 134 insertions(+), 30 deletions(-) diff --git a/apps/webget.cc b/apps/webget.cc index 3b85ce3..4f4a3e9 100644 --- a/apps/webget.cc +++ b/apps/webget.cc @@ -16,9 +16,17 @@ void get_URL(const string &host, const string &path) { // Then you'll need to print out everything the server sends back, // (not just one call to read() -- everything) until you reach // the "eof" (end of file). - - cerr << "Function called: get_URL(" << host << ", " << path << ").\n"; - cerr << "Warning: get_URL() has not been implemented yet.\n"; + TCPSocket sock; + sock.connect(Address(host, "http")); + string request = "GET " + path + " HTTP/1.1\r\nHost: " + host + "\r\nConnection: close\r\n\r\n"; + sock.write(request); + auto recvd = sock.read(); + while (!recvd.empty()) { + cout << recvd; + recvd = sock.read(); + } + // cerr << "Function called: get_URL(" << host << ", " << path << ").\n"; + // cerr << "Warning: get_URL() has not been implemented yet.\n"; } int main(int argc, char *argv[]) { diff --git a/libsponge/byte_stream.cc b/libsponge/byte_stream.cc index 826e028..3777631 100644 --- a/libsponge/byte_stream.cc +++ b/libsponge/byte_stream.cc @@ -1,5 +1,6 @@ #include "byte_stream.hh" +#include // Dummy implementation of a flow-controlled in-memory byte stream. // For Lab 0, please replace with a real implementation that passes the @@ -8,46 +9,65 @@ // You will need to add private members to the class declaration in `byte_stream.hh` template -void DUMMY_CODE(Targs &&... /* unused */) {} +void DUMMY_CODE(Targs &&.../* unused */) {} using namespace std; -ByteStream::ByteStream(const size_t capacity) { DUMMY_CODE(capacity); } +ByteStream::ByteStream(const size_t capacity) { _capacity = capacity; } size_t ByteStream::write(const string &data) { - DUMMY_CODE(data); - return {}; + size_t remain = this->_capacity - this->_buffer.size(); + size_t written = std::min(remain, data.size()); + for (size_t i = 0; i < written; ++i) { + _buffer.push_back(data[i]); + } + this->_written_count += written; + return written; } //! \param[in] len bytes will be copied from the output side of the buffer string ByteStream::peek_output(const size_t len) const { - DUMMY_CODE(len); - return {}; + string output; + size_t avail = std::min(len, _buffer.size()); + for (size_t i = 0; i < avail; ++i) { + output += this->_buffer[i]; + } + return output; } //! \param[in] len bytes will be removed from the output side of the buffer -void ByteStream::pop_output(const size_t len) { DUMMY_CODE(len); } +void ByteStream::pop_output(const size_t len) { + size_t avail = std::min(len, _buffer.size()); + for (size_t i = 0; i < avail; ++i) { + this->_buffer.pop_front(); + } + this->_read_count += avail; + // the test case is more or less stupid here + // it expects read count be updated on return of `pop_output` + // rather than `read` +} //! Read (i.e., copy and then pop) the next "len" bytes of the stream //! \param[in] len bytes will be popped and returned //! \returns a string std::string ByteStream::read(const size_t len) { - DUMMY_CODE(len); - return {}; + std::string data_read = peek_output(len); + pop_output(len); + return data_read; } -void ByteStream::end_input() {} +void ByteStream::end_input() { this->_ended = true; } -bool ByteStream::input_ended() const { return {}; } +bool ByteStream::input_ended() const { return this->_ended; } -size_t ByteStream::buffer_size() const { return {}; } +size_t ByteStream::buffer_size() const { return this->_buffer.size(); } -bool ByteStream::buffer_empty() const { return {}; } +bool ByteStream::buffer_empty() const { return this->_buffer.empty(); } -bool ByteStream::eof() const { return false; } +bool ByteStream::eof() const { return (this->_ended && buffer_empty()); } -size_t ByteStream::bytes_written() const { return {}; } +size_t ByteStream::bytes_written() const { return this->_written_count; } -size_t ByteStream::bytes_read() const { return {}; } +size_t ByteStream::bytes_read() const { return this->_read_count; } -size_t ByteStream::remaining_capacity() const { return {}; } +size_t ByteStream::remaining_capacity() const { return this->_capacity - this->_buffer.size(); } diff --git a/libsponge/byte_stream.hh b/libsponge/byte_stream.hh index 71317c2..ed56baf 100644 --- a/libsponge/byte_stream.hh +++ b/libsponge/byte_stream.hh @@ -1,6 +1,7 @@ #ifndef SPONGE_LIBSPONGE_BYTE_STREAM_HH #define SPONGE_LIBSPONGE_BYTE_STREAM_HH +#include #include //! \brief An in-order byte stream. @@ -18,6 +19,11 @@ class ByteStream { // different approaches. bool _error{}; //!< Flag indicating that the stream suffered an error. + bool _ended{}; + std::deque _buffer{}; + int _capacity{0}; + size_t _written_count{0}; + size_t _read_count{0}; public: //! Construct a stream with room for `capacity` bytes. diff --git a/libsponge/util/eventloop.hh b/libsponge/util/eventloop.hh index 0ca0216..a1ede7a 100644 --- a/libsponge/util/eventloop.hh +++ b/libsponge/util/eventloop.hh @@ -47,11 +47,12 @@ class EventLoop { }; //! Add a rule whose callback will be called when `fd` is ready in the specified Direction. - void add_rule(const FileDescriptor &fd, - const Direction direction, - const CallbackT &callback, - const InterestT &interest = [] { return true; }, - const CallbackT &cancel = [] {}); + void add_rule( + const FileDescriptor &fd, + const Direction direction, + const CallbackT &callback, + const InterestT &interest = [] { return true; }, + const CallbackT &cancel = [] {}); //! Calls [poll(2)](\ref man2::poll) and then executes callback for each ready fd. Result wait_next_event(const int timeout_ms); diff --git a/writeups/lab0.md b/writeups/lab0.md index 92f08ce..d78c91d 100644 --- a/writeups/lab0.md +++ b/writeups/lab0.md @@ -1,15 +1,15 @@ Lab 0 Writeup ============= -My name: [your name here] +My name: [Catfood] -My SUNet ID: [your sunetid here] +My SUNet ID: [998244353] -I collaborated with: [list sunetids here] +I collaborated with: [An orange cat] -This lab took me about [n] hours to do. I [did/did not] attend the lab session. +This lab took me about [2] hours to do. I [did not] attend the lab session. -My secret code from section 2.1 was: [code here] +My secret code from section 2.1 was: [294080] - Optional: I had unexpected difficulty with: [describe] @@ -18,3 +18,72 @@ My secret code from section 2.1 was: [code here] - Optional: I was surprised by: [describe] - Optional: I'm not sure about: [describe] + +2.1.2: +``` +➜ sponge git:(lab0-startercode) ✗ telnet cs144.keithw.org http +Trying 104.196.238.229... +Connected to cs144.keithw.org. +Escape character is '^]'. +GET /hello HTTP/1.1 +Host: cs144.keithw.org +Connection: close + +HTTP/1.1 200 OK +Date: Tue, 14 Feb 2023 14:17:29 GMT +Server: Apache +Last-Modified: Thu, 13 Dec 2018 15:45:29 GMT +ETag: "e-57ce93446cb64" +Accept-Ranges: bytes +Content-Length: 14 +Connection: close +Content-Type: text/plain + +Hello, CS144! +Connection closed by foreign host. +``` + +2.1.3: +``` +➜ sponge git:(lab0-startercode) ✗ telnet cs144.keithw.org http +Trying 104.196.238.229... +Connected to cs144.keithw.org. +Escape character is '^]'. +GET /lab0/998244353 HTTP/1.1 +Host: cs144.keithw.org +Connection: close + +HTTP/1.1 200 OK +Date: Tue, 14 Feb 2023 14:18:54 GMT +Server: Apache +X-You-Said-Your-SunetID-Was: 998244353 +X-Your-Code-Is: 294080 +Content-length: 113 +Vary: Accept-Encoding +Connection: close +Content-Type: text/plain + +Hello! You told us that your SUNet ID was "998244353". Please see the HTTP headers (above) for your secret code. +Connection closed by foreign host. +``` + +2.2: +学校的邮件系统比较智障,做不了 + +2.3 +``` +➜ sponge git:(lab0-startercode) ✗ telnet localhost 9090 +Trying 127.0.0.1... +Connected to localhost. +Escape character is '^]'. +fuck +lalal +Connection closed by foreign host. + +➜ sponge git:(lab0-startercode) ✗ netcat -v -l -p 9090 +Listening on 0.0.0.0 9090 +Connection received on localhost 33706 +fuck +lalal +``` +