void HTTPRequest::read(std::istream& istr) { static const int eof = std::char_traits<char>::eof(); std::string method; std::string uri; std::string version; method.reserve(16); uri.reserve(64); version.reserve(16); int ch = istr.get(); if (istr.bad()) throw NetException("Error reading HTTP request header"); if (ch == eof) throw NoMessageException(); while (Poco::Ascii::isSpace(ch)) ch = istr.get(); if (ch == eof) throw MessageException("No HTTP request header"); while (!Poco::Ascii::isSpace(ch) && ch != eof && method.length() < MAX_METHOD_LENGTH) { method += (char) ch; ch = istr.get(); } if (!Poco::Ascii::isSpace(ch)) throw MessageException("HTTP request method invalid or too long"); while (Poco::Ascii::isSpace(ch)) ch = istr.get(); while (!Poco::Ascii::isSpace(ch) && ch != eof && uri.length() < MAX_URI_LENGTH) { uri += (char) ch; ch = istr.get(); } if (!Poco::Ascii::isSpace(ch)) throw MessageException("HTTP request URI invalid or too long"); while (Poco::Ascii::isSpace(ch)) ch = istr.get(); while (!Poco::Ascii::isSpace(ch) && ch != eof && version.length() < MAX_VERSION_LENGTH) { version += (char) ch; ch = istr.get(); } if (!Poco::Ascii::isSpace(ch)) throw MessageException("Invalid HTTP version string"); while (ch != '\n' && ch != eof) { ch = istr.get(); } HTTPMessage::read(istr); ch = istr.get(); while (ch != '\n' && ch != eof) { ch = istr.get(); } setMethod(method); setURI(uri); setVersion(version); }
void MessageHeader::read(std::istream& istr) { static const int eof = std::char_traits<char>::eof(); int ch = istr.get(); while (ch != eof && ch != '\r' && ch != '\n') { std::string name; std::string value; while (ch != eof && ch != ':' && ch != '\n' && name.length() < MAX_NAME_LENGTH) { name += ch; ch = istr.get(); } if (ch == '\n') { ch = istr.get(); continue; } // ignore invalid header lines if (ch != ':') throw MessageException("Field name too long/no colon found"); if (ch != eof) ch = istr.get(); // ':' while (std::isspace(ch)) ch = istr.get(); while (ch != eof && ch != '\r' && ch != '\n' && value.length() < MAX_VALUE_LENGTH) { value += ch; ch = istr.get(); } if (ch == '\r') ch = istr.get(); if (ch == '\n') ch = istr.get(); else if (ch != eof) throw MessageException("Field value too long/no CRLF found"); while (ch == ' ' || ch == '\t') // folding { while (ch != eof && ch != '\r' && ch != '\n' && value.length() < MAX_VALUE_LENGTH) { value += ch; ch = istr.get(); } if (ch == '\r') ch = istr.get(); if (ch == '\n') ch = istr.get(); else if (ch != eof) throw MessageException("Folded field value too long/no CRLF found"); } add(name, value); } istr.putback(ch); }
void HTTPResponse::read(std::istream& istr) { static const int eof = std::char_traits<char>::eof(); std::string version; std::string status; std::string reason; int ch = istr.get(); if (ch == eof) throw NoMessageException(); while (Poco::Ascii::isSpace(ch)) ch = istr.get(); if (ch == eof) throw MessageException("No HTTP response header"); while (!Poco::Ascii::isSpace(ch) && ch != eof && version.length() < MAX_VERSION_LENGTH) { version += (char) ch; ch = istr.get(); } if (!Poco::Ascii::isSpace(ch)) throw MessageException("Invalid HTTP version string"); while (Poco::Ascii::isSpace(ch)) ch = istr.get(); while (!Poco::Ascii::isSpace(ch) && ch != eof && status.length() < MAX_STATUS_LENGTH) { status += (char) ch; ch = istr.get(); } if (!Poco::Ascii::isSpace(ch)) throw MessageException("Invalid HTTP status code"); while (Poco::Ascii::isSpace(ch) && ch != '\r' && ch != '\n' && ch != eof) ch = istr.get(); while (ch != '\r' && ch != '\n' && ch != eof && reason.length() < MAX_REASON_LENGTH) { reason += (char) ch; ch = istr.get(); } if (!Poco::Ascii::isSpace(ch)) throw MessageException("HTTP reason string too long"); if (ch == '\r') ch = istr.get(); HTTPMessage::read(istr); ch = istr.get(); while (ch != '\n' && ch != eof) { ch = istr.get(); } setVersion(version); setStatus(status); setReason(reason); }
MessageBuffer *Session::ReadMessage() { unsigned char len_buf[4]; unsigned char *buf = NULL; unsigned long msg_len; read_monitor.Enter(); try { if (ReadData(len_buf, 0, 4) != 4) throw MessageException("Unable to read data"); unsigned long msg_len_net = *((unsigned int *)len_buf); msg_len = ntohl(msg_len_net); buf = new unsigned char[msg_len]; if (ReadData(buf, 0, msg_len) != msg_len) throw MessageException("Unable to read data"); } catch (...) { read_monitor.Exit(); if (buf != NULL) delete[] buf; throw; } read_monitor.Exit(); MessageBuffer *rv = new MessageBuffer(); try { rv->SetData(buf, msg_len); } catch (...) { delete[] buf; delete rv; throw; } delete[] buf; return rv; }
void Session::Connect(const char *hostname, unsigned short port) { Socket *s = new Socket(); if (s->Connect(hostname, port) < 0) { delete s; throw MessageException("Failed to connect to server"); } sock = s; // Read the session id from the stream unsigned char buf[4]; if (ReadData(buf, 0, 4) != 4) throw MessageException("Unable to read data"); unsigned long id_net = *((unsigned int *)buf); unsigned long session_id = ntohl(id_net); }
void MessageHeader::read(std::istream& istr) { static const int eof = std::char_traits<char>::eof(); std::streambuf& buf = *istr.rdbuf(); std::string name; std::string value; name.reserve(32); value.reserve(64); int ch = buf.sbumpc(); int fields = 0; while (ch != eof && ch != '\r' && ch != '\n') { if (_fieldLimit > 0 && fields == _fieldLimit) throw MessageException("Too many header fields"); name.clear(); value.clear(); while (ch != eof && ch != ':' && ch != '\n' && name.length() < MAX_NAME_LENGTH) { name += ch; ch = buf.sbumpc(); } if (ch == '\n') { ch = buf.sbumpc(); continue; } // ignore invalid header lines if (ch != ':') throw MessageException("Field name too long/no colon found"); if (ch != eof) ch = buf.sbumpc(); // ':' while (ch != eof && Poco::Ascii::isSpace(ch) && ch != '\r' && ch != '\n') ch = buf.sbumpc(); while (ch != eof && ch != '\r' && ch != '\n' && value.length() < MAX_VALUE_LENGTH) { value += ch; ch = buf.sbumpc(); } if (ch == '\r') ch = buf.sbumpc(); if (ch == '\n') ch = buf.sbumpc(); else if (ch != eof) throw MessageException("Field value too long/no CRLF found"); while (ch == ' ' || ch == '\t') // folding { while (ch != eof && ch != '\r' && ch != '\n' && value.length() < MAX_VALUE_LENGTH) { value += ch; ch = buf.sbumpc(); } if (ch == '\r') ch = buf.sbumpc(); if (ch == '\n') ch = buf.sbumpc(); else if (ch != eof) throw MessageException("Folded field value too long/no CRLF found"); } Poco::trimRightInPlace(value); add(name, value); ++fields; } istr.putback(ch); }
void Session::WriteMessage(const MessageBuffer *msg) { unsigned int msg_len = msg->GetLength(); int len = 4; unsigned long msg_len_net = htonl(msg_len); const unsigned char *data = (unsigned char *)&msg_len_net; write_monitor.Enter(); try { if (WriteData(data, 0, len) != len) throw MessageException("Unable to write data"); len = msg_len; data = msg->GetData(); if (WriteData(data, 0, len) != len) throw MessageException("Unable to write data"); } catch (...) { write_monitor.Exit(); throw; } write_monitor.Exit(); }
void MessageFilter::Write(MessageBuffer &buf) const { throw MessageException("MessageFilter::Write not implemented"); }
bool MessageFilter::Matches(const BaseMessage &message) const { throw MessageException("MessageFilter::Matches not implemented"); }