diff options
-rw-r--r-- | apt-pkg/acquire-method.cc | 17 | ||||
-rw-r--r-- | apt-pkg/contrib/strutl.cc | 10 | ||||
-rw-r--r-- | methods/http.cc | 134 | ||||
-rw-r--r-- | methods/http.h | 9 | ||||
-rw-r--r-- | test/scratch.cc | 6 |
5 files changed, 127 insertions, 49 deletions
diff --git a/apt-pkg/acquire-method.cc b/apt-pkg/acquire-method.cc index 0629995a0..8d26537fa 100644 --- a/apt-pkg/acquire-method.cc +++ b/apt-pkg/acquire-method.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: acquire-method.cc,v 1.2 1998/11/01 05:27:30 jgg Exp $ +// $Id: acquire-method.cc,v 1.3 1998/11/01 08:07:11 jgg Exp $ /* ###################################################################### Acquire Method @@ -47,6 +47,8 @@ pkgAcqMethod::pkgAcqMethod(const char *Ver,unsigned long Flags) exit(100); SetNonBlock(STDIN_FILENO,true); + + Queue = 0; } /*}}}*/ // AcqMethod::Fail - A fetch has failed /*{{{*/ @@ -220,11 +222,11 @@ int pkgAcqMethod::Run(bool Single) if (Single == false) if (WaitFd(STDIN_FILENO) == false) return 0; - } - - if (ReadMessages(STDIN_FILENO,Messages) == false) - return 0; + if (ReadMessages(STDIN_FILENO,Messages) == false) + return 0; + } + // Single mode exits if the message queue is empty if (Single == true && Messages.empty() == true) return 0; @@ -259,8 +261,9 @@ int pkgAcqMethod::Run(bool Single) // Append it to the list FetchItem **I = &Queue; - for (; *I != 0 && (*I)->Next != 0; I = &(*I)->Next); + for (; *I != 0; I = &(*I)->Next); *I = Tmp; + cout << "GOT " << Tmp->Uri << endl; if (Fetch(Tmp) == false) Fail(); @@ -310,7 +313,7 @@ void pkgAcqMethod::Status(const char *Format,...) // sprintf the description char S[1024]; - unsigned int Len = snprintf(S,sizeof(S),"101 Log\nURI: %s\n" + unsigned int Len = snprintf(S,sizeof(S),"101 Status\nURI: %s\n" "Message: ",CurrentURI.c_str()); vsnprintf(S+Len,sizeof(S)-Len,Format,args); diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 2c3106ceb..5efa6f60b 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: strutl.cc,v 1.10 1998/11/01 05:27:37 jgg Exp $ +// $Id: strutl.cc,v 1.11 1998/11/01 08:07:12 jgg Exp $ /* ###################################################################### String Util - Some usefull string functions. @@ -627,7 +627,7 @@ void URI::CopyFrom(string U) // Locate the single / that starts the path for (; I < U.end(); I++) { - if (*I == '/' && I[1] == '/') + if (*I == '/' && I+1 < U.end() && I[1] == '/') I += 2; else if (*I == '/') @@ -641,8 +641,10 @@ void URI::CopyFrom(string U) // We can now write the access and path specifiers Access = string(U,0,FirstColon - U.begin()); if (SingleSlash != U.end()) - Path = string(U,SingleSlash - U.begin() + 1); - + Path = string(U,SingleSlash - U.begin()); + if (Path.empty() == true) + Path = "/"; + // Now we attempt to locate a user:pass@host fragment FirstColon += 3; if (FirstColon >= U.end()) diff --git a/methods/http.cc b/methods/http.cc index 6418a7719..d9ac79912 100644 --- a/methods/http.cc +++ b/methods/http.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: http.cc,v 1.1 1998/11/01 05:30:47 jgg Exp $ +// $Id: http.cc,v 1.2 1998/11/01 08:07:13 jgg Exp $ /* ###################################################################### HTTP Aquire Method - This is the HTTP aquire method for APT. @@ -253,19 +253,25 @@ string LastHost; in_addr LastHostA; bool ServerState::Open() { + // Use the already open connection if possible. + if (ServerFd != -1) + return true; + Close(); - int Port; + int Port = 80; string Host; - if (Proxy.empty() == false) + if (Proxy.empty() == true) { - Port = ServerName.Port; + if (ServerName.Port != 0) + Port = ServerName.Port; Host = ServerName.Host; } else { - Port = Proxy.Port; + if (Proxy.Port != 0) + Port = Proxy.Port; Host = Proxy.Host; } @@ -276,7 +282,7 @@ bool ServerState::Open() // Lookup the host hostent *Addr = gethostbyname(Host.c_str()); if (Addr == 0) - return _error->Errno("gethostbyname","Could not lookup host %s",Host.c_str()); + return _error->Error("Could not resolve '%s'",Host.c_str()); LastHost = Host; LastHostA = *(in_addr *)(Addr->h_addr_list[0]); } @@ -313,8 +319,9 @@ bool ServerState::Close() /*}}}*/ // ServerState::RunHeaders - Get the headers before the data /*{{{*/ // --------------------------------------------------------------------- -/* */ -bool ServerState::RunHeaders() +/* Returns 0 if things are OK, 1 if an IO error occursed and 2 if a header + parse error occured */ +int ServerState::RunHeaders() { State = Header; @@ -325,7 +332,8 @@ bool ServerState::RunHeaders() Result = 0; Size = 0; StartPos = 0; - Encoding = Closes; + Encoding = Closes; + HaveContent = false; time(&Date); do @@ -339,14 +347,14 @@ bool ServerState::RunHeaders() string::const_iterator J = I; for (; J != Data.end() && *J != '\n' && *J != '\r';J++); if (HeaderLine(string(I,J-I)) == false) - return false; + return 2; I = J; } - return true; + return 0; } while (Owner->Go(false,this) == true); - - return false; + + return 1; } /*}}}*/ // ServerState::RunData - Transfer the data from the socket /*{{{*/ @@ -415,7 +423,7 @@ bool ServerState::RunData() while ((Last = Owner->Go(false,this)) == true); if (Last == false) return false; - } + } } else { @@ -460,7 +468,7 @@ bool ServerState::HeaderLine(string Line) string Tag = string(Line,0,Pos); string Val = string(Line,Pos+1); - if (stringcasecmp(Tag,"HTTP") == 0) + if (stringcasecmp(Tag.begin(),Tag.begin()+4,"HTTP") == 0) { // Evil servers return no version if (Line[4] == '/') @@ -480,10 +488,11 @@ bool ServerState::HeaderLine(string Line) return true; } - if (stringcasecmp(Tag,"Content-Length:")) + if (stringcasecmp(Tag,"Content-Length:") == 0) { if (Encoding == Closes) Encoding = Stream; + HaveContent = true; // The length is already set from the Content-Range header if (StartPos != 0) @@ -494,8 +503,16 @@ bool ServerState::HeaderLine(string Line) return true; } - if (stringcasecmp(Tag,"Content-Range:")) + if (stringcasecmp(Tag,"Content-Type:") == 0) + { + HaveContent = true; + return true; + } + + if (stringcasecmp(Tag,"Content-Range:") == 0) { + HaveContent = true; + if (sscanf(Val.c_str(),"bytes %lu-%*u/%lu",&StartPos,&Size) != 2) return _error->Error("The http server sent an invalid Content-Range header"); if ((unsigned)StartPos > Size) @@ -503,14 +520,16 @@ bool ServerState::HeaderLine(string Line) return true; } - if (stringcasecmp(Tag,"Transfer-Encoding:")) + if (stringcasecmp(Tag,"Transfer-Encoding:") == 0) { - if (stringcasecmp(Val,"chunked")) + HaveContent = true; + if (stringcasecmp(Val,"chunked") == 0) Encoding = Chunked; + return true; } - if (stringcasecmp(Tag,"Last-Modified:")) + if (stringcasecmp(Tag,"Last-Modified:") == 0) { if (StrToTime(Val,Date) == false) return _error->Error("Unknown date format"); @@ -568,6 +587,8 @@ void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out) Req += string("Proxy-Authorization: Basic ") + Base64Encode(ProxyAuth) + "\r\n";*/ Req += "User-Agent: Debian APT-HTTP/1.2\r\n\r\n"; +// cout << Req << endl; + Out.Read(Req); } /*}}}*/ @@ -681,6 +702,8 @@ bool HttpMethod::Flush(ServerState *Srv) { if (Srv->In.Write(File->Fd()) == false) return _error->Errno("write","Error writing to file"); + if (Srv->In.IsLimit() == true) + return true; } if (Srv->In.IsLimit() == true || Srv->Encoding == ServerState::Closes) @@ -702,6 +725,10 @@ bool HttpMethod::ServerDie(ServerState *Srv) { if (Srv->In.Write(File->Fd()) == false) return _error->Errno("write","Error writing to the file"); + + // Done + if (Srv->In.IsLimit() == true) + return true; } } @@ -735,7 +762,8 @@ bool HttpMethod::ServerDie(ServerState *Srv) to do. Returns 0 - File is open, 1 - IMS hit - 3 - Unrecoverable error */ + 3 - Unrecoverable error + 4 - Error with error content page */ int HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv) { // Not Modified @@ -752,6 +780,8 @@ int HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv) if (Srv->Result < 200 || Srv->Result >= 300) { _error->Error("%u %s",Srv->Result,Srv->Code); + if (Srv->HaveContent == true) + return 4; return 3; } @@ -801,8 +831,15 @@ int HttpMethod::Loop() { ServerState *Server = 0; + int FailCounter = 0; while (1) { + if (FailCounter >= 2) + { + Fail("Massive Server Brain Damage"); + FailCounter = 0; + } + // We have no commands, wait for some to arrive if (Queue == 0) { @@ -832,14 +869,32 @@ int HttpMethod::Loop() } // Queue the request - SendReq(Queue,Server->In); + SendReq(Queue,Server->Out); - // Handle the header data - if (Server->RunHeaders() == false) + // Fetch the next URL header data from the server. + switch (Server->RunHeaders()) { - Fail(); - continue; - } + case 0: + break; + + // The header data is bad + case 2: + { + _error->Error("Bad header Data"); + Fail(); + continue; + } + + // The server closed a connection during the header get.. + default: + case 1: + { + FailCounter++; + _error->DumpErrors(); + Server->Close(); + continue; + } + }; // Decide what to do. FetchResult Res; @@ -853,8 +908,12 @@ int HttpMethod::Loop() // Run the data if (Server->RunData() == false) Fail(); - - Res.MD5Sum = Srv->In.MD5->Result(); + else + { + Res.MD5Sum = Server->In.MD5->Result(); + URIDone(Res); + } + delete File; File = 0; break; @@ -873,11 +932,26 @@ int HttpMethod::Loop() Fail(); break; } + + // We need to flush the data, the header is like a 404 w/ error text + case 4: + { + Fail(); + + // Send to content to dev/null + File = new FileFd("/dev/null",FileFd::WriteExists); + Server->RunData(); + delete File; + File = 0; + break; + } default: Fail("Internal error"); break; - } + } + + FailCounter = 0; } return 0; diff --git a/methods/http.h b/methods/http.h index d231aa1f1..962fb0027 100644 --- a/methods/http.h +++ b/methods/http.h @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: http.h,v 1.1 1998/11/01 05:30:47 jgg Exp $ +// $Id: http.h,v 1.2 1998/11/01 08:07:14 jgg Exp $ /* ###################################################################### HTTP Aquire Method - This is the HTTP aquire method for APT. @@ -81,10 +81,11 @@ struct ServerState unsigned int Result; char Code[MAXLEN]; - // These are some statistics from the last parsed get line + // These are some statistics from the last parsed header lines unsigned long Size; signed long StartPos; time_t Date; + bool HaveContent; enum {Chunked,Stream,Closes} Encoding; enum {Header, Data} State; @@ -100,7 +101,7 @@ struct ServerState bool Comp(URI Other) {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;}; void Reset() {Major = 0; Minor = 0; Result = 0; Size = 0; StartPos = 0; Encoding = Closes; time(&Date); ServerFd = -1;}; - bool RunHeaders(); + int RunHeaders(); bool RunData(); bool Open(); @@ -121,7 +122,6 @@ class HttpMethod : public pkgAcqMethod public: friend ServerState; - ServerState *Srv; int Depth; FileFd *File; @@ -130,7 +130,6 @@ class HttpMethod : public pkgAcqMethod HttpMethod() : pkgAcqMethod("1.2",SingleInstance | Pipeline | SendConfig) { Depth = 0; - Srv = 0; File = 0; Depth = 0; }; diff --git a/test/scratch.cc b/test/scratch.cc index 7cd43c554..502b31db0 100644 --- a/test/scratch.cc +++ b/test/scratch.cc @@ -8,7 +8,7 @@ int main(int argc,char *argv[]) { signal(SIGPIPE,SIG_IGN); -/* URI Foo(argv[1]); + URI Foo(argv[1]); cout << Foo.Access << '\'' << endl; cout << Foo.Host << '\'' << endl; cout << Foo.Path << '\'' << endl; @@ -16,8 +16,8 @@ int main(int argc,char *argv[]) cout << Foo.Password << '\'' << endl; cout << Foo.Port << endl; - return 0;*/ - + return 0; + pkgInitialize(*_config); pkgSourceList List; |