#include "html_parser.hxx"
#include "buffer_builder.hxx"
#include "board_subject_item.hxx"
-#include "http_get.hxx"
+#include "http_header.hxx"
#include "convert/cp932.hxx"
http::Header Base::get_board_subject_request_header() const {
http::Header request_header;
- request_header["Host"] = host_;
+ request_header.set_host(host_);
return request_header;
}
http::Header Base::get_thread_dat_request_header() const {
http::Header request_header;
- request_header.insert(std::make_pair("Host", host_));
+ request_header.set_host(host_);
if (boost::filesystem::exists(get_thread_file_path())) {
const size_t file_size = boost::filesystem::file_size(get_thread_file_path());
- if (file_size > 0) {
- std::string str = boost::lexical_cast<std::string>(file_size);
- str = "bytes=" + str + "-";
- request_header.insert(std::make_pair("Range", str));
- }
+ if (file_size > 0) request_header.set_range(file_size);
}
return request_header;
}
#include <string>
#include <vector>
#include "board_subject_item.hxx"
-#include "http_get.hxx"
+#include "http_header.hxx"
namespace dialektos {
SubjectIdx idx = SubjectIdx::from_xml(
boost::filesystem::path(bbs_->get_board_subject_idx_path()));
- if (!idx.last_modified_.empty())
- request_header.insert(
- std::make_pair("If-Modified-Since", idx.last_modified_));
+ request_header.set_if_modified_since(idx.last_modified_);
http_getter_.reset(new http::GetInThread(uri, request_header));
http_getter_->signal_end().connect(
ofs.close();
// save the metadata to the file subject.xml
- const http::Header& header = response.get_header();
- http::Header::const_iterator it = header.find("Last-Modified");
- if (it != header.end()) {
- SubjectIdx idx = idx_;
- idx.last_modified_ = it->second;
- idx.to_xml(boost::filesystem::path(bbs_->get_board_subject_idx_path()));
- idx_ = idx;
- }
+ idx_.last_modified_ = response.get_header().get_last_modified();
+ idx_.to_xml(boost::filesystem::path(bbs_->get_board_subject_idx_path()));
}
void BoardWindow::on_http_get_end(bool success) {
// const std::string uri = http_getter_->get_uri();
// const http::Header request_header = http_getter_->get_request_header();
const http::Response response = http_getter_->get_response();
-
+ const boost::system::error_code err = http_getter_->get_error();
http_getter_.reset(0);
+ if (err) {
+ statusbar_.push(err.message());
+ return;
+ }
+
on_refresh_end(response.get_status_line(), response.get_header());
std::vector<SubjectItem> subjects;
void BoardWindow::on_refresh_end(const http::StatusLine& status,
const http::Header& header) {
std::string message = status.get_line();
- http::Header::const_iterator it = header.find("Last-Modified");
- if (it != header.end()) {
+ const std::string last_modified = header.get_last_modified();
+ if (!last_modified.empty()) {
message += " ";
- message += it->second;
+ message += last_modified;
}
statusbar_.push(message);
}
--- /dev/null
+/*
+ * Copyright (C) 2009 by Aiwota Programmer
+ * aiwotaprog@tetteke.tk
+ *
+ * This file is part of Dialektos.
+ *
+ * Dialektos is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dialektos is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dialektos. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "http_client.hxx"
+
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/foreach.hpp>
+#include <boost/format.hpp>
+#include <iostream>
+#include <istream>
+#include <ostream>
+#include <string>
+#include <map>
+#include "http_response.hxx"
+#include "http_status_line.hxx"
+
+
+namespace dialektos {
+
+namespace http {
+
+
+AsyncClient::AsyncClient(
+ boost::asio::io_service& io_service, const std::string& uri,
+ const Header& header) :
+ resolver_(io_service),
+ socket_(io_service),
+ request_(),
+ response_(),
+ content_(),
+ http_version_(),
+ status_code_(),
+ status_message_(),
+ response_header_(),
+ err_() {
+
+ const std::string host = header.get_host();
+ assert(!host.empty());
+
+ std::ostream stream(&request_);
+
+ stream << boost::format("GET %1% HTTP/1.0\r\n") % uri;
+
+ typedef std::map<std::string, std::string>::value_type PairType;
+ BOOST_FOREACH(const PairType& pair, header) {
+ stream << boost::format("%1%: %2%\r\n") % pair.first % pair.second;
+ }
+ stream << "\r\n" << std::flush;
+
+ boost::asio::ip::tcp::resolver::query query(host, "http");
+ resolver_.async_resolve(query,
+ boost::bind(&AsyncClient::handle_resolve, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::iterator));
+}
+
+void AsyncClient::handle_resolve(const boost::system::error_code& err,
+ boost::asio::ip::tcp::resolver::iterator endpoint_iterator) {
+ if (err) {
+ err_ = err;
+ return;
+ }
+
+ boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
+ socket_.async_connect(endpoint,
+ boost::bind(&AsyncClient::handle_connect, this,
+ boost::asio::placeholders::error, ++endpoint_iterator));
+}
+
+void AsyncClient::handle_connect(const boost::system::error_code& err,
+ boost::asio::ip::tcp::resolver::iterator endpoint_iterator) {
+ if (!err) {
+ boost::asio::async_write(socket_, request_,
+ boost::bind(&AsyncClient::handle_write_request, this,
+ boost::asio::placeholders::error));
+ } else if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator()) {
+ socket_.close();
+ boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
+ socket_.async_connect(endpoint,
+ boost::bind(&AsyncClient::handle_connect, this,
+ boost::asio::placeholders::error, ++endpoint_iterator));
+ } else {
+ err_= err;
+ }
+}
+
+void AsyncClient::handle_write_request(const boost::system::error_code& err) {
+ if (err) {
+ err_ = err;
+ return;
+ }
+
+ boost::asio::async_read_until(socket_, response_, "\r\n",
+ boost::bind(&AsyncClient::handle_read_status_line, this,
+ boost::asio::placeholders::error));
+}
+
+void AsyncClient::handle_read_status_line(
+ const boost::system::error_code& err) {
+ if (err) {
+ err_ = err;
+ return;
+ }
+
+ std::istream stream(&response_);
+
+ stream >> http_version_;
+ stream >> status_code_;
+
+ std::string status_message_;
+ std::getline(stream, status_message_);
+
+ if (!stream || !boost::algorithm::starts_with(http_version_, "HTTP/")) {
+ std::cerr << "response is not HTTP" << std::endl;
+ return;
+ }
+
+ boost::asio::async_read_until(socket_, response_, "\r\n\r\n",
+ boost::bind(&AsyncClient::handle_read_headers, this,
+ boost::asio::placeholders::error));
+}
+
+void AsyncClient::handle_read_headers(const boost::system::error_code& err) {
+ if (err) {
+ err_ = err;
+ return;
+ }
+
+ std::istream stream(&response_);
+ std::string line;
+ while (std::getline(stream, line)) {
+ boost::algorithm::trim_right(line);
+ response_header_.set_header_from_line(line);
+ }
+
+ if (response_.size() > 0)
+ content_ << &response_ << std::flush;
+
+ boost::asio::async_read(socket_, response_,
+ boost::asio::transfer_at_least(1),
+ boost::bind(&AsyncClient::handle_read_content, this,
+ boost::asio::placeholders::error));
+}
+
+void AsyncClient::handle_read_content(const boost::system::error_code& err)
+{
+ if (!err) {
+ content_ << &response_ << std::flush;
+
+ boost::asio::async_read(socket_, response_,
+ boost::asio::transfer_at_least(1),
+ boost::bind(&AsyncClient::handle_read_content, this,
+ boost::asio::placeholders::error));
+ } else if (err != boost::asio::error::eof) {
+ err_ = err;
+ }
+}
+
+Response AsyncClient::get_response() const {
+ std::stringstream ss;
+ ss << boost::format("%1% %2% %3%")
+ % http_version_ % status_code_ % status_message_;
+ std::string status_line = ss.str();
+
+ StatusLine status(http_version_, status_code_, status_message_, status_line);
+ return Response(status, response_header_, content_.str());
+}
+
+
+} // namespace http
+
+} // namespace dialektos
--- /dev/null
+/*
+ * Copyright (C) 2009 by Aiwota Programmer
+ * aiwotaprog@tetteke.tk
+ *
+ * This file is part of Dialektos.
+ *
+ * Dialektos is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dialektos is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dialektos. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HTTP_CLIENT_HXX
+#define HTTP_CLIENT_HXX
+
+
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/streambuf.hpp>
+#include <string>
+#include <sstream>
+#include "http_header.hxx"
+#include "http_response.hxx"
+
+
+namespace dialektos {
+
+namespace http {
+
+
+class AsyncClient {
+public:
+ AsyncClient(boost::asio::io_service& io_service,
+ const std::string& uri,
+ const Header& header);
+ Response get_response() const;
+ boost::system::error_code get_error() const { return err_; }
+private:
+ void handle_resolve(const boost::system::error_code& err,
+ boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
+ void handle_connect(const boost::system::error_code& err,
+ boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
+ void handle_write_request(const boost::system::error_code& err);
+ void handle_read_status_line(const boost::system::error_code& err);
+ void handle_read_headers(const boost::system::error_code& err);
+ void handle_read_content(const boost::system::error_code& err);
+
+ boost::asio::ip::tcp::resolver resolver_;
+ boost::asio::ip::tcp::socket socket_;
+ boost::asio::streambuf request_;
+ boost::asio::streambuf response_;
+ std::stringstream content_;
+ std::string http_version_;
+ int status_code_;
+ std::string status_message_;
+ Header response_header_;
+ boost::system::error_code err_;
+};
+
+
+} // namespace http
+
+} // namespace dialektos
+
+
+#endif
#include "http_get.hxx"
#include <sigc++/functors/mem_fun.h>
-#include <boost/xpressive/xpressive.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/asio.hpp>
-#include <boost/foreach.hpp>
-#include <boost/format.hpp>
+#include <boost/asio/io_service.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/thread.hpp>
#include <boost/function.hpp>
-#include <vector>
#include <string>
-#include <sstream>
-#include <map>
-#include <iostream>
+#include "http_client.hxx"
namespace dialektos {
namespace http {
-namespace {
-
-StatusLine from_string_to_status_line(const std::string& _line) {
- using namespace boost::xpressive;
- const sregex regex = "HTTP/"
- >> (s1=_d >> '.' >> _d) >> _s
- >> (s2=-repeat<3>(_d)) >> _s
- >> (s3=*set[_w|_s]);
-
- const std::string line = boost::algorithm::trim_right_copy(_line);
- smatch what;
- if (regex_match(line, what, regex)) {
- const std::string version = what[1];
- const int code = boost::lexical_cast<int>(what[2]);
- const std::string message = what[3];
- return StatusLine(version, code, message, line);
- }
- return StatusLine("", 0, "", line);
-}
-
-Header::value_type from_string_to_header_pair(const std::string& _line) {
- using namespace boost::xpressive;
- const sregex regex = (s1=+set[alnum | '-']) >> ":" >> _s >> (s2=-+_);
-
- const std::string line = boost::algorithm::trim_right_copy(_line);
- smatch what;
- if (regex_match(line, what, regex)) {
- const std::string name = what[1];
- const std::string value = what[2];
- return std::make_pair(name, value);
- }
- return std::make_pair("", "");
-}
-
-Response get(const std::string& uri, const Header& header) {
-
- Header::const_iterator it = header.find("Host");
- assert(it != header.end());
- const std::string host = it->second;
- if (host.empty()) return Response();
-
- boost::asio::ip::tcp::iostream stream(host, "http");
-
-
- stream << boost::format("GET %1% HTTP/1.0\r\n") % uri;
- typedef Header::value_type PairType;
- BOOST_FOREACH(const PairType& pair, header) {
- stream << boost::format("%1%: %2%\r\n") % pair.first % pair.second;
- }
-// stream << "Connection: close\r\n";
- stream << "\r\n";
- stream << std::flush;
-
- std::string line;
- std::getline(stream, line);
-
- StatusLine status = from_string_to_status_line(line);
- if (status.get_version() != "0.9" &&
- status.get_version() != "1.0" &&
- status.get_version() != "1.1") {
- std::cerr << "unknown version: (" << status.get_version() << ") "
- << status.get_line() << std::endl;
- return Response(status, Header(), "");
- }
-
- Header response_header;
- while (std::getline(stream, line)) {
- boost::algorithm::trim_right(line);
- if (line.empty()) break;
-
- Header::value_type field = from_string_to_header_pair(line);
- response_header.insert(field);
- }
-
- std::stringstream ss;
- ss << stream.rdbuf();
- const std::string content = ss.str();
-
- return Response(status, response_header, content);
-}
-
-} // namespace
-
-
GetInThread::GetInThread(const std::string& uri,
const Header& request_header) :
dispatcher_(), signal_end_(),
mutex_(), cancel_(false), thread_(),
- uri_(uri), request_header_(request_header), response_() {
+ uri_(uri), request_header_(request_header), response_(), err_(),
+ io_service_() {
dispatcher_.connect(sigc::mem_fun(*this, &GetInThread::on_end_dispather));
}
void GetInThread::cancel() {
boost::mutex::scoped_lock lock(mutex_);
- cancel_ = true;
+ if (io_service_) {
+ io_service_->stop();
+ cancel_ = true;
+ }
}
bool GetInThread::run() {
void GetInThread::operator()() {
ScopeExit scope_exit(boost::ref(dispatcher_));
- const Response response = get(uri_, request_header_);
- response_.reset(new Response(response));
+ {
+ boost::mutex::scoped_lock lock(mutex_);
+ io_service_.reset(new boost::asio::io_service);
+ }
+ AsyncClient client(*io_service_, uri_, request_header_);
+ io_service_->run();
+ response_.reset(new Response(client.get_response()));
+ err_ = client.get_error();
}
void GetInThread::on_end_dispather() {
thread_.reset(0);
- if (!cancel_) signal_end_(true);
+ io_service_.reset(0);
+ signal_end_(!cancel_);
}
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/scoped_ptr.hpp>
+#include <boost/asio/io_service.hpp>
#include <string>
-#include <map>
+#include "http_header.hxx"
+#include "http_response.hxx"
namespace dialektos {
namespace http {
-typedef std::map<std::string, std::string> Header;
-
-struct StatusLine {
- StatusLine() : version_(), code_(0), message_(), line_() {}
- StatusLine(const std::string& version, int code, const std::string& message,
- const std::string& line) :
- version_(version), code_(code), message_(message), line_(line) {}
-
- const std::string& get_version() const { return version_; }
- int get_code() const { return code_; }
- const std::string& get_message() const { return message_; }
- const std::string& get_line() const { return line_; }
-
-private:
- const std::string version_;
- int code_;
- const std::string message_;
- const std::string line_;
-};
-
-struct Response {
- Response() {}
- Response(const StatusLine& status,
- const Header& header, const std::string& content) :
- status_(status),
- header_(header),
- content_(content) {}
-
- const StatusLine& get_status_line() const { return status_; }
- const Header& get_header() const { return header_; }
- const std::string& get_content() const { return content_; }
-
-private:
- const StatusLine status_;
- const Header header_;
- const std::string content_;
-};
-
struct GetInThread {
typedef sigc::signal<void, bool> SignalEndType;
const std::string& get_uri() const { return uri_;}
const Header& get_request_header() const { return request_header_; }
const Response& get_response() const { return *response_; }
+ boost::system::error_code get_error() const { return err_; }
private:
void on_end_dispather();
const std::string uri_;
Header request_header_;
boost::scoped_ptr<Response> response_;
+ boost::system::error_code err_;
+ boost::scoped_ptr<boost::asio::io_service> io_service_;
};
} // namespace http
--- /dev/null
+/*
+ * Copyright (C) 2009 by Aiwota Programmer
+ * aiwotaprog@tetteke.tk
+ *
+ * This file is part of Dialektos.
+ *
+ * Dialektos is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dialektos is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dialektos. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "http_header.hxx"
+
+#include <boost/xpressive/xpressive.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+#include <string>
+#include <map>
+
+
+namespace dialektos {
+
+namespace http {
+
+
+Header::Header() : map_() {
+}
+
+Header::Header(const Header& rhs) : map_(rhs.map_) {
+}
+
+Header::~Header() {}
+
+void Header::set_header_from_line(const std::string& _line) {
+ using namespace boost::xpressive;
+ const sregex regex = (s1=+set[alnum | '-']) >> ":" >> _s >> (s2=-+_);
+
+ const std::string line = boost::algorithm::trim_right_copy(_line);
+ smatch what;
+ if (regex_match(line, what, regex)) {
+ const std::string name = what[1];
+ const std::string value = what[2];
+ set_header(name, value);
+ }
+}
+
+void Header::set_header(const std::string& name, const std::string& value) {
+ if (!value.empty()) map_[name] = value;
+}
+
+void Header::set_host(const std::string& value) {
+ set_header("Host", value);
+}
+
+void Header::set_if_modified_since(const std::string& value) {
+ set_header("If-Modified-Since", value);
+}
+
+void Header::set_if_none_match(const std::string& value) {
+ set_header("If-None-Match", value);
+}
+
+void Header::set_range(const int value) {
+ const std::string text = boost::lexical_cast<std::string>(value);
+ set_header("Range", "bytes=" + text + "-");
+}
+
+std::string Header::get_header(const std::string& name) const {
+ MapType::const_iterator it = map_.find(name);
+ if (it != map_.end()) return it->second;
+ return "";
+}
+
+std::string Header::get_host() const {
+ return get_header("Host");
+}
+
+std::string Header::get_last_modified() const {
+ return get_header("Last-Modified");
+}
+
+std::string Header::get_etag() const {
+ return get_header("ETag");
+}
+
+std::string Header::get_range() const {
+ return get_header("Range");
+}
+
+
+} // namespace http
+
+} // namespace dialektos
--- /dev/null
+/*
+ * Copyright (C) 2009 by Aiwota Programmer
+ * aiwotaprog@tetteke.tk
+ *
+ * This file is part of Dialektos.
+ *
+ * Dialektos is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dialektos is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dialektos. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HTTP_HEADER_HXX
+#define HTTP_HEADER_HXX
+
+#include <string>
+#include <map>
+
+
+namespace dialektos {
+
+namespace http {
+
+
+struct Header {
+ typedef std::map<std::string, std::string> MapType;
+ typedef MapType::const_iterator const_iterator;
+ typedef MapType::value_type value_type;
+
+ Header();
+ Header(const Header& rhs);
+ ~Header();
+
+ const_iterator begin() const { return map_.begin(); }
+ const_iterator end() const { return map_.end(); }
+
+ void set_header_from_line(const std::string&);
+
+ void set_host(const std::string&);
+ void set_if_modified_since(const std::string&);
+ void set_if_none_match(const std::string&);
+ void set_range(int);
+
+ std::string get_host() const;
+ std::string get_last_modified() const;
+ std::string get_etag() const;
+ std::string get_range() const;
+
+private:
+ void set_header(const std::string&, const std::string&);
+ std::string get_header(const std::string&) const;
+
+ MapType map_;
+};
+
+
+} // namespace http
+
+} // namespace dialektos
+
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 2009 by Aiwota Programmer
+ * aiwotaprog@tetteke.tk
+ *
+ * This file is part of Dialektos.
+ *
+ * Dialektos is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dialektos is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dialektos. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef HTTP_RESPONSE_HXX
+#define HTTP_RESPONSE_HXX
+
+#include <string>
+#include "http_status_line.hxx"
+#include "http_header.hxx"
+
+
+namespace dialektos {
+
+namespace http {
+
+
+struct Response {
+ Response() {}
+ Response(const StatusLine& status,
+ const Header& header, const std::string& content) :
+ status_(status),
+ header_(header),
+ content_(content) {}
+
+ const StatusLine& get_status_line() const { return status_; }
+ const Header& get_header() const { return header_; }
+ const std::string& get_content() const { return content_; }
+
+private:
+ const StatusLine status_;
+ const Header header_;
+ const std::string content_;
+};
+
+
+} // namespace http
+
+} // namespace dialektos
+
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 2009 by Aiwota Programmer
+ * aiwotaprog@tetteke.tk
+ *
+ * This file is part of Dialektos.
+ *
+ * Dialektos is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dialektos is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dialektos. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HTTP_STATUS_LINE_HXX
+#define HTTP_STATUS_LINE_HXX
+
+#include <string>
+
+
+namespace dialektos {
+
+namespace http {
+
+
+struct StatusLine {
+ StatusLine() : version_(), code_(0), message_(), line_() {}
+ StatusLine(const std::string& version, int code, const std::string& message,
+ const std::string& line) :
+ version_(version), code_(code), message_(message), line_(line) {}
+
+ const std::string& get_version() const { return version_; }
+ int get_code() const { return code_; }
+ const std::string& get_message() const { return message_; }
+ const std::string& get_line() const { return line_; }
+
+private:
+ const std::string version_;
+ int code_;
+ const std::string message_;
+ const std::string line_;
+};
+
+
+} // namespace http
+
+} // namespace dialektos
+
+
+
+#endif
const std::string uri = bbs_->get_thread_dat_uri();
http::Header request_header = bbs_->get_thread_dat_request_header();
- if (request_header.find("Range") != request_header.end()) {
- if (!idx_.last_modified_.empty())
- request_header.insert(
- std::make_pair("If-Modified-Since", idx_.last_modified_));
- if (!idx_.etag_.empty())
- request_header.insert(std::make_pair("If-None-Match", idx_.etag_));
+ if (!request_header.get_range().empty()) {
+ request_header.set_if_modified_since(idx_.last_modified_);
+ request_header.set_if_none_match(idx_.etag_);
}
http_getter_.reset(new http::GetInThread(uri, request_header));
// const std::string uri = http_getter_->get_uri();
// const http::Header request_header = http_getter_->get_request_header();
const http::Response response = http_getter_->get_response();
+ const boost::system::error_code err = http_getter_->get_error();
http_getter_.reset(0);
+ if (err) {
+ statusbar_.push(err.message());
+ return;
+ }
+
on_refresh_end(response.get_status_line(), response.get_header());
const int code = response.get_status_line().get_code();
void ThreadWindow::on_refresh_end(const http::StatusLine& status,
const http::Header& header) {
std::string message = status.get_line();
- http::Header::const_iterator it = header.find("Last-Modified");
- if (it != header.end()) {
+ const std::string last_modified = header.get_last_modified();
+ if (!last_modified.empty()) {
message += " ";
- message += it->second;
+ message += last_modified;
}
statusbar_.push(message);
}
if (code == 200)
idx_.title_ = bbs_->get_title_from_string(response.get_content());
- http::Header::const_iterator it = response.get_header().find("Last-Modified");
- if (it != response.get_header().end()) idx_.last_modified_ = it->second;
- it = response.get_header().find("ETag");
- if (it != response.get_header().end()) idx_.etag_ = it->second;
+ idx_.last_modified_ = response.get_header().get_last_modified();
+ idx_.etag_ = response.get_header().get_etag();
idx_.line_count_ = text_view_.get_res_num();