~ubuntu-branches/debian/experimental/apt/experimental

« back to all changes in this revision

Viewing changes to methods/http.cc

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2010-02-18 22:07:23 UTC
  • mfrom: (9.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100218220723-zb7zdh6fmsmp30tr
Tags: 0.7.26~exp2
fix crash when LANGUAGE is not set

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
   ##################################################################### */
26
26
                                                                        /*}}}*/
27
27
// Include Files                                                        /*{{{*/
28
 
#include <apt-pkg/contrib/fileutl.h>
 
28
#include <apt-pkg/fileutl.h>
29
29
#include <apt-pkg/acquire-method.h>
30
 
#include <apt-pkg/contrib/error.h>
31
 
#include <apt-pkg/contrib/hashes.h>
 
30
#include <apt-pkg/error.h>
 
31
#include <apt-pkg/hashes.h>
 
32
#include <apt-pkg/netrc.h>
32
33
 
33
34
#include <sys/stat.h>
34
35
#include <sys/time.h>
42
43
#include <map>
43
44
#include <apti18n.h>
44
45
 
 
46
 
45
47
// Internet stuff
46
48
#include <netdb.h>
47
49
 
49
51
#include "connect.h"
50
52
#include "rfc2553emu.h"
51
53
#include "http.h"
52
 
 
53
54
                                                                        /*}}}*/
54
55
using namespace std;
55
56
 
552
553
      // Evil servers return no version
553
554
      if (Line[4] == '/')
554
555
      {
555
 
         if (sscanf(Line.c_str(),"HTTP/%u.%u %u %[^\n]",&Major,&Minor,
 
556
         if (sscanf(Line.c_str(),"HTTP/%u.%u %u%[^\n]",&Major,&Minor,
556
557
                    &Result,Code) != 4)
557
558
            return _error->Error(_("The HTTP server sent an invalid reply header"));
558
559
      }
560
561
      {
561
562
         Major = 0;
562
563
         Minor = 9;
563
 
         if (sscanf(Line.c_str(),"HTTP %u %[^\n]",&Result,Code) != 2)
 
564
         if (sscanf(Line.c_str(),"HTTP %u%[^\n]",&Result,Code) != 2)
564
565
            return _error->Error(_("The HTTP server sent an invalid reply header"));
565
566
      }
566
567
 
681
682
         and a no-store directive for archives. */
682
683
      sprintf(Buf,"GET %s HTTP/1.1\r\nHost: %s\r\n",
683
684
              Itm->Uri.c_str(),ProperHost.c_str());
684
 
      // only generate a cache control header if we actually want to 
685
 
      // use a cache
686
 
      if (_config->FindB("Acquire::http::No-Cache",false) == false)
687
 
      {
688
 
         if (Itm->IndexFile == true)
689
 
            sprintf(Buf+strlen(Buf),"Cache-Control: max-age=%u\r\n",
690
 
                    _config->FindI("Acquire::http::Max-Age",0));
691
 
         else
692
 
         {
693
 
            if (_config->FindB("Acquire::http::No-Store",false) == true)
694
 
               strcat(Buf,"Cache-Control: no-store\r\n");
695
 
         }       
696
 
      }
697
685
   }
698
 
   // generate a no-cache header if needed
699
 
   if (_config->FindB("Acquire::http::No-Cache",false) == true)
 
686
   // generate a cache control header (if needed)
 
687
   if (_config->FindB("Acquire::http::No-Cache",false) == true) 
 
688
   {
700
689
      strcat(Buf,"Cache-Control: no-cache\r\nPragma: no-cache\r\n");
 
690
   }
 
691
   else
 
692
   {
 
693
      if (Itm->IndexFile == true) 
 
694
      {
 
695
         sprintf(Buf+strlen(Buf),"Cache-Control: max-age=%u\r\n",
 
696
                 _config->FindI("Acquire::http::Max-Age",0));
 
697
      }
 
698
      else
 
699
      {
 
700
         if (_config->FindB("Acquire::http::No-Store",false) == true)
 
701
            strcat(Buf,"Cache-Control: no-store\r\n");
 
702
      }
 
703
   }
701
704
 
702
705
   
703
706
   string Req = Buf;
724
727
      Req += string("Proxy-Authorization: Basic ") + 
725
728
          Base64Encode(Proxy.User + ":" + Proxy.Password) + "\r\n";
726
729
 
 
730
   maybe_add_auth (Uri, _config->FindFile("Dir::Etc::netrc"));
727
731
   if (Uri.User.empty() == false || Uri.Password.empty() == false)
 
732
   {
728
733
      Req += string("Authorization: Basic ") + 
729
734
          Base64Encode(Uri.User + ":" + Uri.Password) + "\r\n";
730
 
   
731
 
   Req += "User-Agent: Debian APT-HTTP/1.3 ("VERSION")\r\n\r\n";
 
735
   }
 
736
   Req += "User-Agent: " + _config->Find("Acquire::http::User-Agent",
 
737
                "Debian APT-HTTP/1.3 ("VERSION")") + "\r\n\r\n";
732
738
   
733
739
   if (Debug == true)
734
740
      cerr << Req << endl;
1067
1073
   PipelineDepth = _config->FindI("Acquire::http::Pipeline-Depth",
1068
1074
                                  PipelineDepth);
1069
1075
   Debug = _config->FindB("Debug::Acquire::http",false);
1070
 
   
 
1076
   AutoDetectProxyCmd = _config->Find("Acquire::http::ProxyAutoDetect");
 
1077
 
 
1078
   // Get the proxy to use
 
1079
   AutoDetectProxy();
 
1080
 
1071
1081
   return true;
1072
1082
}
1073
1083
                                                                        /*}}}*/
1317
1327
   return 0;
1318
1328
}
1319
1329
                                                                        /*}}}*/
 
1330
// HttpMethod::AutoDetectProxy - auto detect proxy                      /*{{{*/
 
1331
// ---------------------------------------------------------------------
 
1332
/* */
 
1333
bool HttpMethod::AutoDetectProxy()
 
1334
{
 
1335
   if (AutoDetectProxyCmd.empty())
 
1336
      return true;
 
1337
 
 
1338
   if (Debug)
 
1339
      clog << "Using auto proxy detect command: " << AutoDetectProxyCmd << endl;
 
1340
 
 
1341
   int Pipes[2] = {-1,-1};
 
1342
   if (pipe(Pipes) != 0)
 
1343
      return _error->Errno("pipe", "Failed to create Pipe");
 
1344
 
 
1345
   pid_t Process = ExecFork();
 
1346
   if (Process == 0)
 
1347
   {
 
1348
      dup2(Pipes[1],STDOUT_FILENO);
 
1349
      SetCloseExec(STDOUT_FILENO,false);
 
1350
      
 
1351
      const char *Args[2];
 
1352
      Args[0] = AutoDetectProxyCmd.c_str();
 
1353
      Args[1] = 0;
 
1354
      execv(Args[0],(char **)Args);
 
1355
      cerr << "Failed to exec method " << Args[0] << endl;
 
1356
      _exit(100);
 
1357
   }
 
1358
   char buf[512];
 
1359
   int InFd = Pipes[0];
 
1360
   if (read(InFd, buf, sizeof(buf)) < 0)
 
1361
      return _error->Errno("read", "Failed to read");
 
1362
   ExecWait(Process, "ProxyAutoDetect");
 
1363
   
 
1364
   if (Debug)
 
1365
      clog << "auto detect command returned: '" << buf << "'" << endl;
 
1366
 
 
1367
   if (strstr(buf, "http://") == buf)
 
1368
      _config->Set("Acquire::http::proxy", _strstrip(buf));
 
1369
 
 
1370
   return true;
 
1371
}
 
1372
                                                                        /*}}}*/
1320
1373
 
1321
1374
int main()
1322
1375
{
1323
1376
   setlocale(LC_ALL, "");
 
1377
   // ignore SIGPIPE, this can happen on write() if the socket
 
1378
   // closes the connection (this is dealt with via ServerDie())
 
1379
   signal(SIGPIPE, SIG_IGN);
1324
1380
 
1325
1381
   HttpMethod Mth;
1326
 
   
1327
1382
   return Mth.Loop();
1328
1383
}
1329
1384