/* */ #include "HttpConnection.h" #include #include "Util.h" #include "message.h" #include "prefs.h" #include "LogFactory.h" #include "DlRetryEx.h" #include "DlAbortEx.h" #include "Request.h" #include "Segment.h" #include "HttpRequest.h" #include "HttpResponse.h" #include "HttpHeaderProcessor.h" #include "HttpHeader.h" #include "Logger.h" #include "Socket.h" #include "Option.h" #include "CookieStorage.h" #include "AuthConfigFactory.h" #include "AuthConfig.h" #include "a2functional.h" namespace aria2 { HttpRequestEntry::HttpRequestEntry(const HttpRequestHandle& httpRequest): _httpRequest(httpRequest), _proc(new HttpHeaderProcessor()) {} HttpRequestEntry::~HttpRequestEntry() {} HttpConnection::HttpConnection(int32_t cuid, const SocketHandle& socket, const Option* op): cuid(cuid), socket(socket), _socketBuffer(socket), option(op), logger(LogFactory::getInstance()) {} std::string HttpConnection::eraseConfidentialInfo(const std::string& request) { std::istringstream istr(request); std::string result; std::string line; while(getline(istr, line)) { static const std::string AUTH_HEADER("Authorization: Basic"); static const std::string PROXY_AUTH_HEADER("Proxy-Authorization: Basic"); if(Util::startsWith(line, AUTH_HEADER)) { result += "Authorization: Basic ********\n"; } else if(Util::startsWith(line, PROXY_AUTH_HEADER)) { result += "Proxy-Authorization: Basic ********\n"; } else { strappend(result, line, "\n"); } } return result; } void HttpConnection::sendRequest(const HttpRequestHandle& httpRequest) { std::string request = httpRequest->createRequest(); logger->info(MSG_SENDING_REQUEST, cuid, eraseConfidentialInfo(request).c_str()); _socketBuffer.feedAndSend(request); SharedHandle entry(new HttpRequestEntry(httpRequest)); outstandingHttpRequests.push_back(entry); } void HttpConnection::sendProxyRequest(const HttpRequestHandle& httpRequest) { std::string request = httpRequest->createProxyRequest(); logger->info(MSG_SENDING_REQUEST, cuid, eraseConfidentialInfo(request).c_str()); _socketBuffer.feedAndSend(request); SharedHandle entry(new HttpRequestEntry(httpRequest)); outstandingHttpRequests.push_back(entry); } HttpResponseHandle HttpConnection::receiveResponse() { if(outstandingHttpRequests.empty()) { throw DL_ABORT_EX(EX_NO_HTTP_REQUEST_ENTRY_FOUND); } HttpRequestEntryHandle entry = outstandingHttpRequests.front(); HttpHeaderProcessorHandle proc = entry->getHttpHeaderProcessor(); unsigned char buf[512]; size_t size = sizeof(buf); socket->peekData(buf, size); if(size == 0) { if(socket->wantRead() || socket->wantWrite()) { return SharedHandle(); } else { throw DL_RETRY_EX(EX_INVALID_RESPONSE); } } proc->update(buf, size); if(!proc->eoh()) { socket->readData(buf, size); return SharedHandle(); } size_t putbackDataLength = proc->getPutBackDataLength(); size -= putbackDataLength; socket->readData(buf, size); logger->info(MSG_RECEIVE_RESPONSE, cuid, proc->getHeaderString().c_str()); SharedHandle httpHeader = proc->getHttpResponseHeader(); HttpResponseHandle httpResponse(new HttpResponse()); httpResponse->setCuid(cuid); httpResponse->setHttpHeader(httpHeader); httpResponse->setHttpRequest(entry->getHttpRequest()); outstandingHttpRequests.pop_front(); return httpResponse; } bool HttpConnection::isIssued(const SegmentHandle& segment) const { for(HttpRequestEntries::const_iterator itr = outstandingHttpRequests.begin(); itr != outstandingHttpRequests.end(); ++itr) { HttpRequestHandle httpRequest = (*itr)->getHttpRequest(); if(httpRequest->getSegment() == segment) { return true; } } return false; } SharedHandle HttpConnection::getFirstHttpRequest() const { if(outstandingHttpRequests.empty()) { return SharedHandle(); } else { return outstandingHttpRequests.front()->getHttpRequest(); } } bool HttpConnection::sendBufferIsEmpty() const { return _socketBuffer.sendBufferIsEmpty(); } void HttpConnection::sendPendingData() { _socketBuffer.send(); } } // namespace aria2