123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- #include "httpload.h"
- /************************************************************/
- /************************************************************/
- httpAgentReader::httpAgentReader(httpSpecialAgent& agent,
- const char* baseUrl,
- bool assumeConnectionClosed,
- bool use_auth,
- int bufSize)
- : Header_()
- , Agent_(agent)
- , Buffer_(new char[bufSize])
- , BufPtr_(Buffer_)
- , BufSize_(bufSize)
- , BufRest_(0)
- {
- HeadRequest = false;
- Header = &Header_;
- if (use_auth)
- HeaderParser.Init(&Header_);
- else
- HeaderParser.Init(Header);
- setAssumeConnectionClosed(assumeConnectionClosed ? 1 : 0);
- Header_.SetBase(baseUrl);
- if (Header_.error)
- State = hp_error;
- else
- State = hp_in_header;
- }
- /************************************************************/
- httpAgentReader::~httpAgentReader() {
- delete[] Buffer_;
- }
- /************************************************************/
- void httpAgentReader::readBuf() {
- assert(BufRest_ == 0);
- if (!BufPtr_) {
- BufRest_ = -1;
- return;
- }
- BufRest_ = Agent_.read(Buffer_, BufSize_);
- if (BufRest_ <= 0) {
- BufRest_ = -1;
- BufPtr_ = nullptr;
- } else {
- BufPtr_ = Buffer_;
- //cout << "BUF: " << mBuffer << endl << endl;
- }
- }
- /************************************************************/
- const THttpHeader* httpAgentReader::readHeader() {
- while (State == hp_in_header) {
- if (!step()) {
- Header_.error = HTTP_CONNECTION_LOST;
- return nullptr;
- }
- ParseGeneric(BufPtr_, BufRest_);
- }
- if (State == hp_eof || State == hp_error) {
- BufPtr_ = nullptr;
- BufRest_ = -1;
- }
- if (State == hp_error || Header_.error)
- return nullptr;
- return &Header_;
- }
- /************************************************************/
- long httpAgentReader::readPortion(void*& buf) {
- assert(State != hp_in_header);
- long Chunk = 0;
- do {
- if (BufSize_ == 0 && !BufPtr_)
- return 0;
- if (!step())
- return 0;
- Chunk = ParseGeneric(BufPtr_, BufRest_);
- buf = BufPtr_;
- if (State == hp_error && Header_.entity_size > Header_.content_length) {
- Chunk -= (Header_.entity_size - Header_.content_length);
- BufPtr_ = (char*)BufPtr_ + Chunk;
- BufRest_ = 0;
- State = hp_eof;
- Header_.error = 0;
- break;
- }
- BufPtr_ = (char*)BufPtr_ + Chunk;
- BufRest_ -= Chunk;
- if (State == hp_eof || State == hp_error) {
- BufRest_ = -1;
- BufPtr_ = nullptr;
- }
- } while (!Chunk);
- return Chunk;
- }
- /************************************************************/
- bool httpAgentReader::skipTheRest() {
- void* b;
- while (!eof())
- readPortion(b);
- return (State == hp_eof);
- }
- /************************************************************/
- /************************************************************/
- httpLoadAgent::httpLoadAgent(bool handleAuthorization,
- socketHandlerFactory& factory)
- : Factory_(factory)
- , HandleAuthorization_(handleAuthorization)
- , URL_()
- , PersistentConn_(false)
- , Reader_(nullptr)
- , Headers_()
- , ErrCode_(0)
- , RealHost_(nullptr)
- {
- }
- /************************************************************/
- httpLoadAgent::~httpLoadAgent() {
- delete Reader_;
- free(RealHost_);
- }
- /************************************************************/
- void httpLoadAgent::clearReader() {
- if (Reader_) {
- bool opened = false;
- if (PersistentConn_) {
- const THttpHeader* H = Reader_->readHeader();
- if (H && !H->connection_closed) {
- Reader_->skipTheRest();
- opened = true;
- }
- }
- if (!opened)
- Disconnect();
- delete Reader_;
- Reader_ = nullptr;
- }
- ErrCode_ = 0;
- }
- /************************************************************/
- void httpLoadAgent::setRealHost(const char* hostname) {
- free(RealHost_);
- if (hostname)
- RealHost_ = strdup(hostname);
- else
- RealHost_ = nullptr;
- ErrCode_ = 0;
- }
- /************************************************************/
- void httpLoadAgent::setIMS(const char* ifModifiedSince) {
- char ims_buf[100];
- snprintf(ims_buf, 100, "If-Modified-Since: %s\r\n",
- ifModifiedSince);
- Headers_.push_back(ims_buf);
- }
- /************************************************************/
- void httpLoadAgent::addHeaderInstruction(const char* instr) {
- Headers_.push_back(instr);
- }
- /************************************************************/
- void httpLoadAgent::dropHeaderInstructions() {
- Headers_.clear();
- }
- /************************************************************/
- bool httpLoadAgent::startRequest(const THttpURL& url,
- bool persistent,
- const TAddrList& addrs)
- {
- clearReader();
- ErrCode_ = 0;
- URL_.Clear();
- URL_ = url;
- PersistentConn_ = persistent;
- if (!URL_.IsValidAbs())
- return false;
- if (!HandleAuthorization_ && !URL_.IsNull(THttpURL::FlagAuth))
- return false;
- return doSetHost(addrs) && doStartRequest();
- }
- /************************************************************/
- bool httpLoadAgent::startRequest(const char* url,
- const char* url_to_merge,
- bool persistent,
- const TAddrList& addrs) {
- clearReader();
- URL_.Clear();
- PersistentConn_ = persistent;
- ui64 flags = THttpURL::FeatureSchemeKnown | THttpURL::FeaturesNormalizeSet;
- if (HandleAuthorization_)
- flags |= THttpURL::FeatureAuthSupported;
- if (URL_.Parse(url, flags, url_to_merge) || !URL_.IsValidGlobal())
- return false;
- return doSetHost(addrs) && doStartRequest();
- }
- /************************************************************/
- bool httpLoadAgent::startRequest(const char* url,
- const char* url_to_merge,
- bool persistent,
- ui32 ip) {
- clearReader();
- URL_.Clear();
- PersistentConn_ = persistent;
- ui64 flags = THttpURL::FeatureSchemeKnown | THttpURL::FeaturesNormalizeSet;
- if (HandleAuthorization_)
- flags |= THttpURL::FeatureAuthSupported;
- if (URL_.Parse(url, flags, url_to_merge) || !URL_.IsValidGlobal())
- return false;
- return doSetHost(TAddrList::MakeV4Addr(ip, URL_.GetPort())) && doStartRequest();
- }
- /************************************************************/
- bool httpLoadAgent::doSetHost(const TAddrList& addrs) {
- socketAbstractHandler* h = Factory_.chooseHandler(URL_);
- if (!h)
- return false;
- Socket.setHandler(h);
- if (addrs.size()) {
- ErrCode_ = SetHost(URL_.Get(THttpURL::FieldHost),
- URL_.GetPort(), addrs);
- } else {
- ErrCode_ = SetHost(URL_.Get(THttpURL::FieldHost),
- URL_.GetPort());
- }
- if (ErrCode_)
- return false;
- if (RealHost_) {
- free(Hostheader);
- Hostheader = (char*)malloc(strlen(RealHost_) + 20);
- sprintf(Hostheader, "Host: %s\r\n", RealHost_);
- }
- if (!URL_.IsNull(THttpURL::FlagAuth)) {
- if (!HandleAuthorization_) {
- ErrCode_ = HTTP_UNAUTHORIZED;
- return false;
- }
- Digest_.setAuthorization(URL_.Get(THttpURL::FieldUsername),
- URL_.Get(THttpURL::FieldPassword));
- }
- return true;
- }
- /************************************************************/
- bool httpLoadAgent::setHost(const char* host_url,
- const TAddrList& addrs) {
- clearReader();
- URL_.Clear();
- PersistentConn_ = true;
- ui64 flags = THttpURL::FeatureSchemeKnown | THttpURL::FeaturesNormalizeSet;
- if (HandleAuthorization_)
- flags |= THttpURL::FeatureAuthSupported;
- if (URL_.Parse(host_url, flags) || !URL_.IsValidGlobal())
- return false;
- return doSetHost(addrs);
- }
- /************************************************************/
- bool httpLoadAgent::startOneRequest(const char* local_url) {
- clearReader();
- THttpURL lURL;
- if (lURL.Parse(local_url, THttpURL::FeaturesNormalizeSet) || lURL.IsValidGlobal())
- return false;
- URL_.SetInMemory(THttpURL::FieldPath, lURL.Get(THttpURL::FieldPath));
- URL_.SetInMemory(THttpURL::FieldQuery, lURL.Get(THttpURL::FieldQuery));
- URL_.Rewrite();
- return doStartRequest();
- }
- /************************************************************/
- bool httpLoadAgent::doStartRequest() {
- TString urlStr = URL_.PrintS(THttpURL::FlagPath | THttpURL::FlagQuery);
- if (!urlStr)
- urlStr = "/";
- for (int step = 0; step < 10; step++) {
- const char* digestHeader = Digest_.getHeaderInstruction();
- unsigned i = (digestHeader) ? 2 : 1;
- const char** headers =
- (const char**)(alloca((i + Headers_.size()) * sizeof(char*)));
- for (i = 0; i < Headers_.size(); i++)
- headers[i] = Headers_[i].c_str();
- if (digestHeader)
- headers[i++] = digestHeader;
- headers[i] = nullptr;
- ErrCode_ = RequestGet(urlStr.c_str(), headers, PersistentConn_);
- if (ErrCode_) {
- Disconnect();
- return false;
- }
- TString urlBaseStr = URL_.PrintS(THttpURL::FlagNoFrag);
- clearReader();
- Reader_ = new httpAgentReader(*this, urlBaseStr.c_str(),
- !PersistentConn_, !Digest_.empty());
- if (Reader_->readHeader()) {
- //mReader->getHeader()->Print();
- if (getHeader()->http_status == HTTP_UNAUTHORIZED &&
- step < 1 &&
- Digest_.processHeader(getAuthHeader(),
- urlStr.c_str(),
- "GET")) {
- //mReader->skipTheRest();
- delete Reader_;
- Reader_ = nullptr;
- ErrCode_ = 0;
- Disconnect();
- continue;
- }
- return true;
- }
- Disconnect();
- clearReader();
- return false;
- }
- ErrCode_ = HTTP_UNAUTHORIZED;
- return false;
- }
- /************************************************************/
- /************************************************************/
|