From 492f957ad42ce5eee7e26f3edd5789af296b7460 Mon Sep 17 00:00:00 2001 From: Arch Librarian Date: Mon, 20 Sep 2004 16:51:18 +0000 Subject: Http method Author: jgg Date: 1998-11-04 07:10:49 GMT Http method --- methods/http.cc | 98 +++++++++++++++++++++++++++++++++++++++++++++++---------- methods/http.h | 8 ++++- 2 files changed, 89 insertions(+), 17 deletions(-) (limited to 'methods') diff --git a/methods/http.cc b/methods/http.cc index d9ac79912..4c773b064 100644 --- a/methods/http.cc +++ b/methods/http.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: http.cc,v 1.2 1998/11/01 08:07:13 jgg Exp $ +// $Id: http.cc,v 1.3 1998/11/04 07:10:49 jgg Exp $ /* ###################################################################### HTTP Aquire Method - This is the HTTP aquire method for APT. @@ -36,6 +36,7 @@ #include #include #include +#include #include // Internet stuff @@ -47,6 +48,10 @@ #include "http.h" /*}}}*/ +string HttpMethod::FailFile; +int HttpMethod::FailFd = -1; +time_t HttpMethod::FailTime = 0; + // CircleBuf::CircleBuf - Circular input buffer /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -258,10 +263,25 @@ bool ServerState::Open() return true; Close(); - + In.Reset(); + Out.Reset(); + + // Determine the proxy setting + string DefProxy = _config->Find("Acquire::http::Proxy",getenv("http_proxy")); + string SpecificProxy = _config->Find("Acquire::http::Proxy::" + ServerName.Host); + if (SpecificProxy.empty() == false) + { + if (SpecificProxy == "DIRECT") + Proxy = ""; + else + Proxy = SpecificProxy; + } + else + Proxy = DefProxy; + + // Determine what host and port to use based on the proxy settings int Port = 80; - string Host; - + string Host; if (Proxy.empty() == true) { if (ServerName.Port != 0) @@ -275,6 +295,9 @@ bool ServerState::Open() Host = Proxy.Host; } + /* We used a cached address record.. Yes this is against the spec but + the way we have setup our rotating dns suggests that this is more + sensible */ if (LastHost != Host) { Owner->Status("Connecting to %s",Host.c_str()); @@ -312,8 +335,6 @@ bool ServerState::Close() { close(ServerFd); ServerFd = -1; - In.Reset(); - Out.Reset(); return true; } /*}}}*/ @@ -556,7 +577,12 @@ void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out) ProperHost += Buf; } - // Build the request + /* Build the request. We include a keep-alive header only for non-proxy + requests. This is to tweak old http/1.0 servers that do support keep-alive + but not HTTP/1.1 automatic keep-alive. Doing this with a proxy server + will glitch HTTP/1.0 proxies because they do not filter it out and + pass it on, HTTP/1.1 says the connection should default to keep alive + and we expect the proxy to do this */ if (Proxy.empty() == true) sprintf(Buf,"GET %s HTTP/1.1\r\nHost: %s\r\nConnection: keep-alive\r\n", Uri.Path.c_str(),ProperHost.c_str()); @@ -564,7 +590,7 @@ void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out) sprintf(Buf,"GET %s HTTP/1.1\r\nHost: %s\r\n", Itm->Uri.c_str(),ProperHost.c_str()); string Req = Buf; - + // Check for a partial file struct stat SBuf; if (stat(Itm->DestFile.c_str(),&SBuf) >= 0 && SBuf.st_size > 0) @@ -794,7 +820,11 @@ int HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv) File = new FileFd(Queue->DestFile,FileFd::WriteAny); if (_error->PendingError() == true) return 3; - + + FailFile = Queue->DestFile; + FailFd = File->Fd(); + FailTime = Srv->Date; + // Set the expected size if (Srv->StartPos >= 0) { @@ -824,11 +854,34 @@ int HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv) return 0; } /*}}}*/ -// HttpMethod::Loop /*{{{*/ +// HttpMethod::SigTerm - Handle a fatal signal /*{{{*/ +// --------------------------------------------------------------------- +/* This closes and timestamps the open file. This is neccessary to get + resume behavoir on user abort */ +void HttpMethod::SigTerm(int) +{ + if (FailFd == -1) + exit(100); + close(FailFd); + + // Timestamp + struct utimbuf UBuf; + time(&UBuf.actime); + UBuf.actime = FailTime; + UBuf.modtime = FailTime; + utime(FailFile.c_str(),&UBuf); + + exit(100); +} + /*}}}*/ +// HttpMethod::Loop - Main loop /*{{{*/ // --------------------------------------------------------------------- /* */ int HttpMethod::Loop() { + signal(SIGTERM,SigTerm); + signal(SIGINT,SigTerm); + ServerState *Server = 0; int FailCounter = 0; @@ -906,16 +959,29 @@ int HttpMethod::Loop() URIStart(Res); // Run the data - if (Server->RunData() == false) - Fail(); - else + bool Result = Server->RunData(); + + // Close the file, destroy the FD object and timestamp it + FailFd = -1; + delete File; + File = 0; + + // Timestamp + struct utimbuf UBuf; + time(&UBuf.actime); + UBuf.actime = Server->Date; + UBuf.modtime = Server->Date; + utime(Queue->DestFile.c_str(),&UBuf); + + // Send status to APT + if (Result == true) { Res.MD5Sum = Server->In.MD5->Result(); URIDone(Res); } - - delete File; - File = 0; + else + Fail(); + break; } diff --git a/methods/http.h b/methods/http.h index 962fb0027..62f329ef5 100644 --- a/methods/http.h +++ b/methods/http.h @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: http.h,v 1.2 1998/11/01 08:07:14 jgg Exp $ +// $Id: http.h,v 1.3 1998/11/04 07:10:50 jgg Exp $ /* ###################################################################### HTTP Aquire Method - This is the HTTP aquire method for APT. @@ -119,6 +119,12 @@ class HttpMethod : public pkgAcqMethod bool ServerDie(ServerState *Srv); int DealWithHeaders(FetchResult &Res,ServerState *Srv); + // In the event of a fatal signal this file will be closed and timestamped. + static string FailFile; + static int FailFd; + static time_t FailTime; + static void SigTerm(int); + public: friend ServerState; -- cgit v1.2.3