|
|
@@ -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 <sys/time.h>
|
|
|
#include <utime.h>
|
|
|
#include <unistd.h>
|
|
|
+#include <signal.h>
|
|
|
#include <stdio.h>
|
|
|
|
|
|
// 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;
|
|
|
}
|
|
|
|