~ubuntu-branches/ubuntu/quantal/apt-cacher-ng/quantal-backports

« back to all changes in this revision

Viewing changes to source/job.cc

  • Committer: Bazaar Package Importer
  • Author(s): Eduard Bloch
  • Date: 2010-07-28 01:17:33 UTC
  • mfrom: (1.1.24 upstream)
  • Revision ID: james.westby@ubuntu.com-20100728011733-kocsb0jjhzu76ees
Tags: 0.5.1-1
* New upstream version
  + header inclusion cleanup (closes: #590291)
  + kfreebsd related fixes
  + long outstanding user interface fixes and various regression fixes

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#include "acfg.h"
13
13
#include "fileitem.h"
14
14
#include "dlcon.h"
 
15
#include "sockio.h"
15
16
 
16
17
#include "maintenance.h"
17
18
 
21
22
 
22
23
#include <errno.h>
23
24
 
24
 
// optimization on Linux; no-op for platforms that don't know it
25
 
#ifndef MSG_MORE
26
 
#define MSG_MORE 0
27
 
#endif
28
 
 
29
25
#define REPLEVEL (m_type==rechecks::FILE_INDEX ? 4 : (m_type==rechecks::FILE_PKG ? 5 : SPAMLEVEL))
30
26
 
31
27
//void DispatchAndRunMaintTask(const MYSTD::string &, int, const MYSTD::string &);
230
226
 
231
227
    LOGSTART("job::PrepareDownload");
232
228
    
233
 
    string sTmp; // for raw uri and other tasks
 
229
    string sRawUriPath, sPathResdiual;
234
230
    tHttpUrl tUrl; // parsed URL
235
231
        
236
232
    acfg::tHostiVec * pBackends(NULL); // appropriate backends
263
259
                
264
260
                tStrVec tmp;
265
261
                if(3 == Tokenize(m_pReqHead->frontLine, SPACECHARS, tmp))
266
 
                        sTmp=tmp[1];
 
262
                        sRawUriPath=tmp[1];
267
263
                else
268
264
                        goto report_invpath; // invalid uri
269
265
        }
270
 
    
 
266
 
 
267
 
271
268
    MYTRY
272
269
        {
 
270
        LOG("raw uri: " << sRawUriPath);
273
271
        // filesystem browsing attempt?
274
 
                if(stmiss != sTmp.find("..") || stmiss != sTmp.find("/_actmp"))
 
272
                if(stmiss != sRawUriPath.find("..") || stmiss != sRawUriPath.find("/_actmp"))
275
273
                        goto report_notallowed;
276
274
 
277
 
                if (0==sTmp.compare(0, 12, "apt-cacher?/"))
278
 
                sTmp.erase(0, 12);
279
 
                if (0==sTmp.compare(0, 11, "apt-cacher/"))
280
 
                sTmp.erase(11);
 
275
                if (0==sRawUriPath.compare(0, 12, "apt-cacher?/"))
 
276
                sRawUriPath.erase(0, 12);
 
277
                if (0==sRawUriPath.compare(0, 11, "apt-cacher/"))
 
278
                sRawUriPath.erase(11);
281
279
                
282
 
                if(!tUrl.SetHttpUrl(sTmp))      goto report_info;
 
280
                if(!tUrl.SetHttpUrl(sRawUriPath))
 
281
                {
 
282
                        m_sMaintCmd="/";
 
283
                        return;
 
284
                }
 
285
                LOG("refined path: " << tUrl.sPath);
283
286
 
284
287
                if(!tUrl.sPort.empty() && tUrl.sPort!="80")
285
288
                {
302
305
                LOG("input uri: "<<tUrl.ToURI()<<" , dontcache-flag? " << bPtMode);
303
306
 
304
307
                tStrPos nRepNameLen=acfg::reportpage.size();
305
 
                if(nRepNameLen>0 && 0==tUrl.sHost.compare(0, nRepNameLen, acfg::reportpage))
306
 
                {
307
 
                        m_sMaintCmd=tUrl.sHost;
 
308
                if(nRepNameLen>0)
 
309
                {
 
310
                        if(0==tUrl.sHost.compare(0, nRepNameLen, acfg::reportpage))
 
311
                        {
 
312
                                m_sMaintCmd=tUrl.sHost;
 
313
                                return;
 
314
                        }
 
315
                        if (tUrl.sHost == "style.css")
 
316
                        {
 
317
                                LOG("support CSS style file");
 
318
                                m_sMaintCmd = "/style.css";
 
319
                                return;
 
320
                        }
 
321
                }
 
322
                if(!sPath.empty() && endsWithSzAr(sPath, "/"))
 
323
                {
 
324
                        LOG("generic user information page");
 
325
                        m_sMaintCmd="/";
308
326
                        return;
309
327
                }
310
 
                if(!tUrl.sPath.empty() && tUrl.sPath[tUrl.sPath.size()-1]=='/' )
311
 
                        goto report_info;
 
328
 
 
329
 
312
330
                m_type = rechecks::GetFiletype(sPath);
313
331
 
314
332
                if ( m_type == rechecks::FILE_INVALID ) goto report_notallowed;
315
333
                
316
334
                // got something valid, has type now, trace it
317
 
                USRDBG(REPLEVEL, "Processing new job, " << m_pReqHead->frontLine);
 
335
                USRDBG(REPLEVEL, string("Processing new job, ")+m_pReqHead->frontLine);
318
336
 
319
337
                // resolve to an internal location
320
 
                psVname = acfg::GetRepNameAndPathResidual(tUrl, sTmp);
 
338
                psVname = acfg::GetRepNameAndPathResidual(tUrl, sPathResdiual);
321
339
                
322
340
                if(psVname)
323
 
                        m_sFileLoc=*psVname+sPathSep+sTmp;
 
341
                        m_sFileLoc=*psVname+sPathSep+sPathResdiual;
324
342
                else
325
343
                        m_sFileLoc=tUrl.sHost+tUrl.sPath;
326
344
                
389
407
                {
390
408
                        if(psVname && NULL != (pBackends=acfg::GetBackendVec(psVname)))
391
409
                        {
392
 
                                LOG("Backends found, using them with " << sTmp
 
410
                                LOG("Backends found, using them with " << sPathResdiual
393
411
                                                << ", first backend: " <<pBackends->front().ToURI());
394
412
 
395
 
                                if(! bPtMode && rechecks::MatchUncacheableTarget(pBackends->front().ToURI()+sTmp))
 
413
                                if(! bPtMode && rechecks::MatchUncacheableTarget(pBackends->front().ToURI()+sPathResdiual))
396
414
                                        fistate=_SwitchToPtItem(m_sFileLoc);
397
415
 
398
 
                                m_pParentCon->m_pDlClient->AddJob(m_pItem, pBackends, sTmp);
 
416
                                m_pParentCon->m_pDlClient->AddJob(m_pItem, pBackends, sPathResdiual);
399
417
                        }
400
418
                        else
401
419
                        {
426
444
 
427
445
report_notallowed:
428
446
    m_sErrorMsgBuffer="403 Forbidden file type or location";
 
447
    USRDBG(5, m_sErrorMsgBuffer+": "+sRawUriPath);
429
448
    return ;
430
449
 
431
450
report_offlineconf:
445
464
                "Inconsistent apt configuration?";
446
465
    return ;
447
466
 
448
 
    report_info:
449
 
    m_sMaintCmd="/";
450
 
    return;
451
467
}
452
468
 
453
469
#define THROW_ERROR(x) { m_sErrorMsgBuffer=x; goto THROWN_ERROR; }
523
539
                                                return tempRes;
524
540
                                        if(szTempErr)
525
541
                                                THROW_ERROR(szTempErr);
526
 
                                        USRDBG(REPLEVEL, "Prepared response header for user: \n" << m_sPrependBuf);
 
542
                                        USRDBG(REPLEVEL, "Prepared response header for user: \n" + m_sPrependBuf);
527
543
                                        continue;
528
544
                                }
529
545
                                case(STATE_HEADER_SENT):
664
680
                                        LOG("or STATE_ERRORCONT?");
665
681
                                case(STATE_FINISHJOB):
666
682
                                        LOG("or STATE_FINISHJOB");
667
 
                                LOG("what's the head? " << m_pReqHead << " and close flag? "
668
 
                                                << (m_pReqHead ? "(unset)" : m_pReqHead->h[header::CONNECTION] ));
 
683
                                        {
 
684
                                                bool bClose=true;
 
685
                                                if(m_pReqHead)
 
686
                                                {
 
687
                                                        bool bhttp11 = m_pReqHead->frontLine.find("HTTP/1.1") != stmiss;
 
688
                                                        if(m_pReqHead->h[header::CONNECTION])
 
689
                                                                bClose = 0==strcasecmp(m_pReqHead->h[header::CONNECTION], "close");
 
690
                                                        else
 
691
                                                                bClose = !bhttp11;
 
692
                                                }
669
693
 
670
 
                                        if(m_pReqHead && m_pReqHead->h[header::CONNECTION])
671
 
                                        {
672
 
                                                LOG("close-Header found, advising to disconnect");
673
 
                                                if(0==strcasecmp(m_pReqHead->h[header::CONNECTION], "close"))
 
694
                                                if(bClose)
674
695
                                                        return R_DISCON;
 
696
                                                LOG("Reporting job done")
 
697
                                                return R_DONE;
675
698
                                        }
676
 
                                        LOG("Reporting job done")
677
 
                                        return R_DONE;
 
699
                                        break;
678
700
                                case(STATE_TODISCON):
679
701
                                default:
680
702
                                        return R_DISCON;
757
779
        // if missing completely, chunked mode is to be used below
758
780
        if(m_RespHead.h[header::CONTENT_LENGTH])
759
781
        {
760
 
                if(0==atol(m_RespHead.h[header::CONTENT_LENGTH]))
 
782
                if(0==atoofft(m_RespHead.h[header::CONTENT_LENGTH]))
761
783
                        bSendBody=false;
762
784
 
763
785
                /*
804
826
                        // is it fresh? or is this relevant? or is range mode forced?
805
827
                        if(  bFreshnessForced || bIfModSeenAndChecked)
806
828
                        {
807
 
                                off_t nContLen=atol(m_RespHead.h[header::CONTENT_LENGTH]);
 
829
                                off_t nContLen=atoofft(m_RespHead.h[header::CONTENT_LENGTH]);
808
830
 
809
831
                                /*
810
832
                                 * Range: bytes=453291-