diff --git a/src/main/native/cpp/HttpCameraImpl.cpp b/src/main/native/cpp/HttpCameraImpl.cpp index ce8f5f644f..40fc736ac9 100644 --- a/src/main/native/cpp/HttpCameraImpl.cpp +++ b/src/main/native/cpp/HttpCameraImpl.cpp @@ -79,7 +79,7 @@ void HttpCameraImpl::StreamThreadMain() { // connect llvm::SmallString<64> boundary; - HttpConnection* conn = DeviceStreamConnect(boundary); + wpi::HttpConnection* conn = DeviceStreamConnect(boundary); if (!m_active) break; @@ -97,10 +97,10 @@ void HttpCameraImpl::StreamThreadMain() { SetConnected(false); } -HttpConnection* HttpCameraImpl::DeviceStreamConnect( +wpi::HttpConnection* HttpCameraImpl::DeviceStreamConnect( llvm::SmallVectorImpl& boundary) { // Build the request - HttpRequest req; + wpi::HttpRequest req; { std::lock_guard lock(m_mutex); if (m_locations.empty()) { @@ -109,7 +109,7 @@ HttpConnection* HttpCameraImpl::DeviceStreamConnect( return nullptr; } if (m_nextLocation >= m_locations.size()) m_nextLocation = 0; - req = HttpRequest{m_locations[m_nextLocation++], m_streamSettings}; + req = wpi::HttpRequest{m_locations[m_nextLocation++], m_streamSettings}; m_streamSettingsUpdated = false; } @@ -119,8 +119,8 @@ HttpConnection* HttpCameraImpl::DeviceStreamConnect( if (!m_active || !stream) return nullptr; - auto connPtr = llvm::make_unique(std::move(stream), 1); - HttpConnection* conn = connPtr.get(); + auto connPtr = llvm::make_unique(std::move(stream), 1); + wpi::HttpConnection* conn = connPtr.get(); // update m_streamConn { @@ -128,7 +128,9 @@ HttpConnection* HttpCameraImpl::DeviceStreamConnect( m_streamConn = std::move(connPtr); } - if (!conn->Handshake(req, GetName())) { + std::string warn; + if (!conn->Handshake(req, &warn)) { + SWARNING(GetName() << ": " << warn); std::lock_guard lock(m_mutex); m_streamConn = nullptr; return nullptr; @@ -254,7 +256,7 @@ bool HttpCameraImpl::DeviceStreamFrame(wpi::raw_istream& is, void HttpCameraImpl::SettingsThreadMain() { for (;;) { - HttpRequest req; + wpi::HttpRequest req; { std::unique_lock lock(m_mutex); m_settingsCond.wait(lock, [=] { @@ -263,7 +265,7 @@ void HttpCameraImpl::SettingsThreadMain() { if (!m_active) break; // Build the request - req = HttpRequest{m_locations[m_prefLocation], m_settings}; + req = wpi::HttpRequest{m_locations[m_prefLocation], m_settings}; } DeviceSendSettings(req); @@ -272,15 +274,15 @@ void HttpCameraImpl::SettingsThreadMain() { SDEBUG("Settings Thread exiting"); } -void HttpCameraImpl::DeviceSendSettings(HttpRequest& req) { +void HttpCameraImpl::DeviceSendSettings(wpi::HttpRequest& req) { // Try to connect auto stream = wpi::TCPConnector::connect(req.host.c_str(), req.port, Logger::GetInstance(), 1); if (!m_active || !stream) return; - auto connPtr = llvm::make_unique(std::move(stream), 1); - HttpConnection* conn = connPtr.get(); + auto connPtr = llvm::make_unique(std::move(stream), 1); + wpi::HttpConnection* conn = connPtr.get(); // update m_settingsConn { @@ -289,7 +291,8 @@ void HttpCameraImpl::DeviceSendSettings(HttpRequest& req) { } // Just need a handshake as settings are sent via GET parameters - conn->Handshake(req, GetName()); + std::string warn; + if (!conn->Handshake(req, &warn)) SWARNING(GetName() << ": " << warn); conn->stream->close(); } @@ -301,11 +304,13 @@ CS_HttpCameraKind HttpCameraImpl::GetKind() const { bool HttpCameraImpl::SetUrls(llvm::ArrayRef urls, CS_Status* status) { - std::vector locations; + std::vector locations; for (const auto& url : urls) { bool error = false; - locations.emplace_back(url, &error, GetName()); + std::string errorMsg; + locations.emplace_back(url, &error, &errorMsg); if (error) { + SERROR(GetName() << ": " << errorMsg); *status = CS_BAD_URL; return false; } diff --git a/src/main/native/cpp/HttpCameraImpl.h b/src/main/native/cpp/HttpCameraImpl.h index b4c726be9d..a8d3863726 100644 --- a/src/main/native/cpp/HttpCameraImpl.h +++ b/src/main/native/cpp/HttpCameraImpl.h @@ -19,9 +19,9 @@ #include #include +#include #include -#include "HttpUtil.h" #include "SourceImpl.h" #include "cscore_cpp.h" @@ -100,13 +100,14 @@ class HttpCameraImpl : public SourceImpl { void StreamThreadMain(); // Functions used by StreamThreadMain() - HttpConnection* DeviceStreamConnect(llvm::SmallVectorImpl& boundary); + wpi::HttpConnection* DeviceStreamConnect( + llvm::SmallVectorImpl& boundary); void DeviceStream(wpi::raw_istream& is, llvm::StringRef boundary); bool DeviceStreamFrame(wpi::raw_istream& is, std::string& imageBuf); // The camera settings thread void SettingsThreadMain(); - void DeviceSendSettings(HttpRequest& req); + void DeviceSendSettings(wpi::HttpRequest& req); std::atomic_bool m_connected{false}; std::atomic_bool m_active{true}; // set to false to terminate thread @@ -118,12 +119,12 @@ class HttpCameraImpl : public SourceImpl { // // The camera connections - std::unique_ptr m_streamConn; - std::unique_ptr m_settingsConn; + std::unique_ptr m_streamConn; + std::unique_ptr m_settingsConn; CS_HttpCameraKind m_kind; - std::vector m_locations; + std::vector m_locations; size_t m_nextLocation{0}; int m_prefLocation{-1}; // preferred location diff --git a/src/main/native/cpp/HttpUtil.cpp b/src/main/native/cpp/HttpUtil.cpp deleted file mode 100644 index 55b7fb1c87..0000000000 --- a/src/main/native/cpp/HttpUtil.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#include "HttpUtil.h" - -#include - -#include -#include -#include -#include - -#include "Log.h" - -namespace cs { - -llvm::StringRef ReadLine(wpi::raw_istream& is, llvm::SmallVectorImpl& buf, - int maxLen, bool* error) { - buf.clear(); - for (int i = 0; i < maxLen; ++i) { - char c; - is.read(c); - if (is.has_error()) { - *error = true; - return llvm::StringRef{buf.data(), buf.size()}; - } - if (c == '\r') continue; - buf.push_back(c); - if (c == '\n') break; - } - *error = false; - return llvm::StringRef{buf.data(), buf.size()}; -} - -llvm::StringRef UnescapeURI(llvm::StringRef str, - llvm::SmallVectorImpl& buf, bool* error) { - buf.clear(); - for (auto i = str.begin(), end = str.end(); i != end; ++i) { - // pass non-escaped characters to output - if (*i != '%') { - // decode + to space - if (*i == '+') - buf.push_back(' '); - else - buf.push_back(*i); - continue; - } - - // are there enough characters left? - if (i + 2 >= end) { - *error = true; - return llvm::StringRef{}; - } - - // replace %xx with the corresponding character - unsigned val1 = llvm::hexDigitValue(*++i); - if (val1 == -1U) { - *error = true; - return llvm::StringRef{}; - } - unsigned val2 = llvm::hexDigitValue(*++i); - if (val2 == -1U) { - *error = true; - return llvm::StringRef{}; - } - buf.push_back((val1 << 4) | val2); - } - - *error = false; - return llvm::StringRef{buf.data(), buf.size()}; -} - -llvm::StringRef EscapeURI(llvm::StringRef str, llvm::SmallVectorImpl& buf, - bool spacePlus) { - static const char* const hexLut = "0123456789ABCDEF"; - - buf.clear(); - for (auto i = str.begin(), end = str.end(); i != end; ++i) { - // pass unreserved characters to output - if (std::isalnum(*i) || *i == '-' || *i == '_' || *i == '.' || *i == '~') { - buf.push_back(*i); - continue; - } - - // encode space to + - if (spacePlus && *i == ' ') { - buf.push_back('+'); - continue; - } - - // convert others to %xx - buf.push_back('%'); - buf.push_back(hexLut[((*i) >> 4) & 0x0f]); - buf.push_back(hexLut[(*i) & 0x0f]); - } - - return llvm::StringRef{buf.data(), buf.size()}; -} - -bool ParseHttpHeaders(wpi::raw_istream& is, - llvm::SmallVectorImpl* contentType, - llvm::SmallVectorImpl* contentLength) { - if (contentType) contentType->clear(); - if (contentLength) contentLength->clear(); - - bool inContentType = false; - bool inContentLength = false; - llvm::SmallString<64> lineBuf; - for (;;) { - bool error; - llvm::StringRef line = ReadLine(is, lineBuf, 1024, &error).rtrim(); - if (error) return false; - if (line.empty()) return true; // empty line signals end of headers - - // header fields start at the beginning of the line - if (!std::isspace(line[0])) { - inContentType = false; - inContentLength = false; - llvm::StringRef field; - std::tie(field, line) = line.split(':'); - field = field.rtrim(); - if (field == "Content-Type") - inContentType = true; - else if (field == "Content-Length") - inContentLength = true; - else - continue; // ignore other fields - } - - // collapse whitespace - line = line.ltrim(); - - // save field data - if (inContentType && contentType) - contentType->append(line.begin(), line.end()); - else if (inContentLength && contentLength) - contentLength->append(line.begin(), line.end()); - } -} - -bool FindMultipartBoundary(wpi::raw_istream& is, llvm::StringRef boundary, - std::string* saveBuf) { - llvm::SmallString<64> searchBuf; - searchBuf.resize(boundary.size() + 2); - size_t searchPos = 0; - - // Per the spec, the --boundary should be preceded by \r\n, so do a first - // pass of 1-byte reads to throw those away (common case) and keep the - // last non-\r\n character in searchBuf. - if (!saveBuf) { - do { - is.read(searchBuf.data(), 1); - if (is.has_error()) return false; - } while (searchBuf[0] == '\r' || searchBuf[0] == '\n'); - searchPos = 1; - } - - // Look for --boundary. Read boundarysize+2 bytes at a time - // during the search to speed up the reads, then fast-scan for -, - // and only then match the entire boundary. This will be slow if - // there's a bunch of continuous -'s in the output, but that's unlikely. - for (;;) { - is.read(searchBuf.data() + searchPos, searchBuf.size() - searchPos); - if (is.has_error()) return false; - - // Did we find the boundary? - if (searchBuf[0] == '-' && searchBuf[1] == '-' && - searchBuf.substr(2) == boundary) - return true; - - // Fast-scan for '-' - size_t pos = searchBuf.find('-', searchBuf[0] == '-' ? 1 : 0); - if (pos == llvm::StringRef::npos) { - if (saveBuf) saveBuf->append(searchBuf.data(), searchBuf.size()); - } else { - if (saveBuf) saveBuf->append(searchBuf.data(), pos); - - // move '-' and following to start of buffer (next read will fill) - std::memmove(searchBuf.data(), searchBuf.data() + pos, - searchBuf.size() - pos); - searchPos = searchBuf.size() - pos; - } - } -} - -HttpLocation::HttpLocation(llvm::StringRef url_, bool* error, - llvm::StringRef cameraName) - : url{url_} { - // Split apart into components - llvm::StringRef query{url_}; - - // scheme: - llvm::StringRef scheme; - std::tie(scheme, query) = query.split(':'); - if (!scheme.equals_lower("http")) { - ERROR(cameraName << ": only supports http URLs, got \"" << url << "\""); - *error = true; - return; - } - - // "//" - if (!query.startswith("//")) { - ERROR(cameraName << ": expected http://..., got \"" << url << "\""); - *error = true; - return; - } - query = query.drop_front(2); - - // user:password@host:port/ - llvm::StringRef authority; - std::tie(authority, query) = query.split('/'); - - llvm::StringRef userpass, hostport; - std::tie(userpass, hostport) = authority.split('@'); - // split leaves the RHS empty if the split char isn't present... - if (hostport.empty()) { - hostport = userpass; - userpass = llvm::StringRef{}; - } - - if (!userpass.empty()) { - llvm::StringRef rawUser, rawPassword; - std::tie(rawUser, rawPassword) = userpass.split(':'); - llvm::SmallString<64> userBuf, passBuf; - user = UnescapeURI(rawUser, userBuf, error); - if (*error) { - ERROR(cameraName << ": could not unescape user \"" << rawUser - << "\" in \"" << url << "\""); - return; - } - password = UnescapeURI(rawPassword, passBuf, error); - if (*error) { - ERROR(cameraName << ": could not unescape password \"" << rawPassword - << "\" in \"" << url << "\""); - return; - } - } - - llvm::StringRef portStr; - std::tie(host, portStr) = hostport.rsplit(':'); - if (host.empty()) { - ERROR(cameraName << ": host is empty in \"" << url << "\""); - *error = true; - return; - } - if (portStr.empty()) { - port = 80; - } else if (portStr.getAsInteger(10, port)) { - ERROR(cameraName << ": port \"" << portStr << "\" is not an integer in \"" - << url << "\""); - *error = true; - return; - } - - // path?query#fragment - std::tie(query, fragment) = query.split('#'); - std::tie(path, query) = query.split('?'); - - // Split query string into parameters - while (!query.empty()) { - // split out next param and value - llvm::StringRef rawParam, rawValue; - std::tie(rawParam, query) = query.split('&'); - if (rawParam.empty()) continue; // ignore "&&" - std::tie(rawParam, rawValue) = rawParam.split('='); - - // unescape param - *error = false; - llvm::SmallString<64> paramBuf; - llvm::StringRef param = UnescapeURI(rawParam, paramBuf, error); - if (*error) { - ERROR(cameraName << ": could not unescape parameter \"" << rawParam - << "\" in \"" << url << "\""); - return; - } - - // unescape value - llvm::SmallString<64> valueBuf; - llvm::StringRef value = UnescapeURI(rawValue, valueBuf, error); - if (*error) { - ERROR(cameraName << ": could not unescape value \"" << rawValue - << "\" in \"" << url << "\""); - return; - } - - params.emplace_back(std::make_pair(param, value)); - } - - *error = false; -} - -void HttpRequest::SetAuth(const HttpLocation& loc) { - if (!loc.user.empty()) { - llvm::SmallString<64> userpass; - userpass += loc.user; - userpass += ':'; - userpass += loc.password; - wpi::Base64Encode(userpass, &auth); - } -} - -bool HttpConnection::Handshake(const HttpRequest& request, - llvm::StringRef cameraName) { - // send GET request - os << "GET /" << request.path << " HTTP/1.1\r\n"; - os << "Host: " << request.host << "\r\n"; - if (!request.auth.empty()) - os << "Authorization: Basic " << request.auth << "\r\n"; - os << "\r\n"; - os.flush(); - - // read first line of response - bool error = false; - llvm::SmallString<64> lineBuf; - llvm::StringRef line = ReadLine(is, lineBuf, 1024, &error).rtrim(); - if (error) { - WARNING(cameraName << ": \"" << request.host - << "\": disconnected before response"); - return false; - } - - // see if we got a HTTP 200 response - llvm::StringRef httpver, code, codeText; - std::tie(httpver, line) = line.split(' '); - std::tie(code, codeText) = line.split(' '); - if (!httpver.startswith("HTTP")) { - WARNING(cameraName << ": \"" << request.host - << "\": did not receive HTTP response"); - return false; - } - if (code != "200") { - WARNING(cameraName << ": \"" << request.host << "\": received " << code - << " " << codeText << " response"); - return false; - } - - // Parse headers - if (!ParseHttpHeaders(is, &contentType, &contentLength)) { - WARNING(cameraName << ": \"" << request.host - << "\": disconnected during headers"); - return false; - } - - return true; -} - -} // namespace cs diff --git a/src/main/native/cpp/HttpUtil.h b/src/main/native/cpp/HttpUtil.h deleted file mode 100644 index 1a19d29066..0000000000 --- a/src/main/native/cpp/HttpUtil.h +++ /dev/null @@ -1,157 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) 2016-2017 FIRST. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef CSCORE_HTTPUTIL_H_ -#define CSCORE_HTTPUTIL_H_ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace cs { - -// Read a line from an input stream (up to a maximum length). -// The returned buffer will contain the trailing \n (unless the maximum length -// was reached). \r's are stripped from the buffer. -// @param buf Buffer for output -// @param error Set to true if an error occurred -// @return Line -llvm::StringRef ReadLine(wpi::raw_istream& is, llvm::SmallVectorImpl& buf, - int maxLen, bool* error); - -// Unescape a %xx-encoded URI. -// @param buf Buffer for output -// @param error Set to true if an error occurred -// @return Escaped string -llvm::StringRef UnescapeURI(llvm::StringRef str, - llvm::SmallVectorImpl& buf, bool* error); - -// Escape a string with %xx-encoding. -// @param buf Buffer for output -// @param spacePlus If true, encodes spaces to '+' rather than "%20" -// @return Escaped string -llvm::StringRef EscapeURI(llvm::StringRef str, llvm::SmallVectorImpl& buf, - bool spacePlus = true); - -// Parse a set of HTTP headers. Saves just the Content-Type and Content-Length -// fields. -// @param is Input stream -// @param contentType If not null, Content-Type contents are saved here. -// @param contentLength If not null, Content-Length contents are saved here. -// @return False if error occurred in input stream -bool ParseHttpHeaders(wpi::raw_istream& is, - llvm::SmallVectorImpl* contentType, - llvm::SmallVectorImpl* contentLength); - -// Look for a MIME multi-part boundary. On return, the input stream will -// be located at the character following the boundary (usually "\r\n"). -// @param is Input stream -// @param boundary Boundary string to scan for (not including "--" prefix) -// @param saveBuf If not null, all scanned characters up to but not including -// the boundary are saved to this string -// @return False if error occurred on input stream, true if boundary found. -bool FindMultipartBoundary(wpi::raw_istream& is, llvm::StringRef boundary, - std::string* saveBuf); - -class HttpLocation { - public: - HttpLocation() = default; - HttpLocation(llvm::StringRef url_, bool* error, llvm::StringRef cameraName); - - std::string url; // retain copy - std::string user; // unescaped - std::string password; // unescaped - std::string host; - int port; - std::string path; // escaped, not including leading '/' - std::vector> params; // unescaped - std::string fragment; -}; - -class HttpRequest { - public: - HttpRequest() = default; - - explicit HttpRequest(const HttpLocation& loc) - : host{loc.host}, port{loc.port} { - SetPath(loc.path, loc.params); - SetAuth(loc); - } - - template - HttpRequest(const HttpLocation& loc, const T& extraParams); - - HttpRequest(const HttpLocation& loc, llvm::StringRef path_) - : host{loc.host}, port{loc.port}, path{path_} { - SetAuth(loc); - } - - template - HttpRequest(const HttpLocation& loc, llvm::StringRef path_, const T& params) - : host{loc.host}, port{loc.port} { - SetPath(path_, params); - SetAuth(loc); - } - - llvm::SmallString<128> host; - int port; - std::string auth; - llvm::SmallString<128> path; - - private: - void SetAuth(const HttpLocation& loc); - template - void SetPath(llvm::StringRef path_, const T& params); - - template - static llvm::StringRef GetFirst(const T& elem) { - return elem.first; - } - template - static llvm::StringRef GetFirst(const llvm::StringMapEntry& elem) { - return elem.getKey(); - } - template - static llvm::StringRef GetSecond(const T& elem) { - return elem.second; - } -}; - -class HttpConnection { - public: - HttpConnection(std::unique_ptr stream_, int timeout) - : stream{std::move(stream_)}, is{*stream, timeout}, os{*stream, true} {} - - bool Handshake(const HttpRequest& request, llvm::StringRef cameraName); - - std::unique_ptr stream; - wpi::raw_socket_istream is; - wpi::raw_socket_ostream os; - - // Valid after Handshake() is successful - llvm::SmallString<64> contentType; - llvm::SmallString<64> contentLength; - - explicit operator bool() const { return stream && !is.has_error(); } -}; - -} // namespace cs - -#include "HttpUtil.inl" - -#endif // CSCORE_HTTPUTIL_H_ diff --git a/src/main/native/cpp/HttpUtil.inl b/src/main/native/cpp/HttpUtil.inl deleted file mode 100644 index 1ea992f277..0000000000 --- a/src/main/native/cpp/HttpUtil.inl +++ /dev/null @@ -1,48 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef HTTPUTIL_INL_ -#define HTTPUTIL_INL_ - -namespace cs { - -template -HttpRequest::HttpRequest(const HttpLocation& loc, const T& extraParams) - : host{loc.host}, port{loc.port} { - llvm::StringMap params; - for (const auto& p : loc.params) - params.insert(std::make_pair(GetFirst(p), GetSecond(p))); - for (const auto& p : extraParams) - params.insert(std::make_pair(GetFirst(p), GetSecond(p))); - SetPath(loc.path, params); - SetAuth(loc); -} - -template -void HttpRequest::SetPath(llvm::StringRef path_, const T& params) { - // Build location including query string - llvm::raw_svector_ostream pathOs{path}; - pathOs << path_; - bool first = true; - for (const auto& param : params) { - if (first) { - pathOs << '?'; - first = false; - } else { - pathOs << '&'; - } - llvm::SmallString<64> escapeBuf; - pathOs << EscapeURI(GetFirst(param), escapeBuf); - if (!GetSecond(param).empty()) { - pathOs << '=' << EscapeURI(GetSecond(param), escapeBuf); - } - } -} - -} // namespace cs - -#endif // HTTPUTIL_INL_ diff --git a/src/main/native/cpp/MjpegServerImpl.cpp b/src/main/native/cpp/MjpegServerImpl.cpp index 1b5ca107b6..21ae2c8f85 100644 --- a/src/main/native/cpp/MjpegServerImpl.cpp +++ b/src/main/native/cpp/MjpegServerImpl.cpp @@ -10,12 +10,12 @@ #include #include +#include #include #include #include #include "Handle.h" -#include "HttpUtil.h" #include "JpegUtil.h" #include "Log.h" #include "Notifier.h" @@ -203,7 +203,7 @@ bool MjpegServerImpl::ConnThread::ProcessCommand(llvm::raw_ostream& os, // unescape param bool error = false; llvm::SmallString<64> paramBuf; - llvm::StringRef param = UnescapeURI(rawParam, paramBuf, &error); + llvm::StringRef param = wpi::UnescapeURI(rawParam, paramBuf, &error); if (error) { llvm::SmallString<128> error; llvm::raw_svector_ostream oss{error}; @@ -215,7 +215,7 @@ bool MjpegServerImpl::ConnThread::ProcessCommand(llvm::raw_ostream& os, // unescape value llvm::SmallString<64> valueBuf; - llvm::StringRef value = UnescapeURI(rawValue, valueBuf, &error); + llvm::StringRef value = wpi::UnescapeURI(rawValue, valueBuf, &error); if (error) { llvm::SmallString<128> error; llvm::raw_svector_ostream oss{error}; @@ -681,10 +681,9 @@ void MjpegServerImpl::ConnThread::ProcessRequest() { m_fps = 0; // Read the request string from the stream - bool error = false; llvm::SmallString<128> reqBuf; - llvm::StringRef req = ReadLine(is, reqBuf, 4096, &error); - if (error) { + llvm::StringRef req = is.getline(reqBuf, 4096); + if (is.has_error()) { SDEBUG("error getting request string"); return; } @@ -738,8 +737,8 @@ void MjpegServerImpl::ConnThread::ProcessRequest() { // The end of the request is marked by a single, empty line llvm::SmallString<128> lineBuf; for (;;) { - if (ReadLine(is, lineBuf, 4096, &error).startswith("\n")) break; - if (error) return; + if (is.getline(lineBuf, 4096).startswith("\n")) break; + if (is.has_error()) return; } // Send response diff --git a/src/main/native/cpp/UsbUtil.cpp b/src/main/native/cpp/UsbUtil.cpp index 6cd1044b77..929bfcba44 100644 --- a/src/main/native/cpp/UsbUtil.cpp +++ b/src/main/native/cpp/UsbUtil.cpp @@ -19,7 +19,6 @@ #include #include -#include "HttpUtil.h" #include "Log.h" namespace cs { @@ -44,9 +43,8 @@ static llvm::StringRef GetUsbNameFromFile(int vendor, int product, llvm::SmallString<128> lineBuf; bool foundVendor = false; for (;;) { - bool error = false; - auto line = ReadLine(is, lineBuf, 4096, &error); - if (error) break; + auto line = is.getline(lineBuf, 4096); + if (is.has_error()) break; if (line.empty()) continue;