~ubuntu-branches/ubuntu/oneiric/squid3/oneiric-security

« back to all changes in this revision

Viewing changes to src/http.cc

  • Committer: Bazaar Package Importer
  • Author(s): Mahyuddin Susanto
  • Date: 2011-02-15 18:46:13 UTC
  • mfrom: (21.2.4 sid)
  • Revision ID: james.westby@ubuntu.com-20110215184613-1u3dh5sz4i055flk
Tags: 3.1.10-1ubuntu1
* Merge from debian unstable. (LP: #719283)  Remaining changes:
  - debian/patches/18-fix-ftbfs-binutils-gold.dpatch: Add library linker into
    LIBS instead to LDFLAGS to fixing FTBFS binutils-gold.
* Drop Ubuntu configuration for ufw which landed in Debian and sync it: 
  - debian/squid3.ufw.profile.

Show diffs side-by-side

added added

removed removed

Lines of Context:
139
139
     * register the handler to free HTTP state data when the FD closes
140
140
     */
141
141
    typedef CommCbMemFunT<HttpStateData, CommCloseCbParams> Dialer;
142
 
    closeHandler = asyncCall(9, 5, "httpStateData::httpStateConnClosed",
143
 
                             Dialer(this,&HttpStateData::httpStateConnClosed));
 
142
    closeHandler = JobCallback(9, 5,
 
143
                               Dialer, this, HttpStateData::httpStateConnClosed);
144
144
    comm_add_close_handler(fd, closeHandler);
145
145
}
146
146
 
372
372
    if (surrogateNoStore)
373
373
        return 0;
374
374
 
 
375
    // RFC 2616: do not cache replies to responses with no-store CC directive
 
376
    if (request && request->cache_control &&
 
377
            EBIT_TEST(request->cache_control->mask, CC_NO_STORE) &&
 
378
            !REFRESH_OVERRIDE(ignore_no_store))
 
379
        return 0;
 
380
 
375
381
    if (!ignoreCacheControl) {
376
382
        if (EBIT_TEST(cc_mask, CC_PRIVATE)) {
377
383
            if (!REFRESH_OVERRIDE(ignore_private))
681
687
        tmprep->header.putExt("X-Transformed-From", "HTTP/0.9");
682
688
        mb = tmprep->pack();
683
689
        newrep->parse(mb, eof, &error);
 
690
        delete mb;
684
691
        delete tmprep;
685
692
    } else {
686
693
        if (!parsed && error > 0) { // unrecoverable parsing error
708
715
        readBuf->consume(header_bytes_read);
709
716
    }
710
717
 
 
718
    newrep->removeStaleWarnings();
 
719
 
711
720
    /* Skip 1xx messages for now. Advertised in Via as an internal 1.0 hop */
712
721
    if (newrep->sline.protocol == PROTO_HTTP && newrep->sline.status >= 100 && newrep->sline.status < 200) {
713
722
 
729
738
    }
730
739
 
731
740
    flags.chunked = 0;
732
 
    if (newrep->sline.protocol == PROTO_HTTP && newrep->header.hasListMember(HDR_TRANSFER_ENCODING, "chunked", ',')) {
 
741
    if (newrep->sline.protocol == PROTO_HTTP && newrep->header.chunked()) {
733
742
        flags.chunked = 1;
734
743
        httpChunkDecoder = new ChunkedCodingParser;
735
744
    }
896
905
no_cache:
897
906
 
898
907
    if (!ignoreCacheControl && rep->cache_control) {
899
 
        if (EBIT_TEST(rep->cache_control->mask, CC_PROXY_REVALIDATE))
900
 
            EBIT_SET(entry->flags, ENTRY_REVALIDATE);
901
 
        else if (EBIT_TEST(rep->cache_control->mask, CC_MUST_REVALIDATE))
 
908
        if (EBIT_TEST(rep->cache_control->mask, CC_PROXY_REVALIDATE) ||
 
909
                EBIT_TEST(rep->cache_control->mask, CC_MUST_REVALIDATE) ||
 
910
                EBIT_TEST(rep->cache_control->mask, CC_S_MAXAGE))
902
911
            EBIT_SET(entry->flags, ENTRY_REVALIDATE);
903
912
    }
904
913
 
958
967
HttpStateData::persistentConnStatus() const
959
968
{
960
969
    debugs(11, 3, "persistentConnStatus: FD " << fd << " eof=" << eof);
961
 
    const HttpReply *vrep = virginReply();
962
 
    debugs(11, 5, "persistentConnStatus: content_length=" << vrep->content_length);
963
 
 
964
 
    /* If we haven't seen the end of reply headers, we are not done */
965
 
    debugs(11, 5, "persistentConnStatus: flags.headers_parsed=" << flags.headers_parsed);
966
 
 
967
 
    if (!flags.headers_parsed)
968
 
        return INCOMPLETE_MSG;
969
 
 
970
970
    if (eof) // already reached EOF
971
971
        return COMPLETE_NONPERSISTENT_MSG;
972
972
 
 
973
    /* If server fd is closing (but we have not been notified yet), stop Comm
 
974
       I/O to avoid assertions. TODO: Change Comm API to handle callers that
 
975
       want more I/O after async closing (usually initiated by others). */
 
976
    // XXX: add canReceive or s/canSend/canTalkToServer/
 
977
    if (!canSend(fd))
 
978
        return COMPLETE_NONPERSISTENT_MSG;
 
979
 
973
980
    /** \par
974
981
     * In chunked response we do not know the content length but we are absolutely
975
982
     * sure about the end of response, so we are calling the statusIfComplete to
978
985
    if (lastChunk && flags.chunked)
979
986
        return statusIfComplete();
980
987
 
 
988
    const HttpReply *vrep = virginReply();
 
989
    debugs(11, 5, "persistentConnStatus: content_length=" << vrep->content_length);
 
990
 
981
991
    const int64_t clen = vrep->bodySize(request->method);
982
992
 
983
993
    debugs(11, 5, "persistentConnStatus: clen=" << clen);
1406
1416
        flags.do_next_read = 0;
1407
1417
        typedef CommCbMemFunT<HttpStateData, CommIoCbParams> Dialer;
1408
1418
        entry->delayAwareRead(fd, readBuf->space(read_size), read_size,
1409
 
                              asyncCall(11, 5, "HttpStateData::readReply",
1410
 
                                        Dialer(this, &HttpStateData::readReply)));
 
1419
                              JobCallback(11, 5, Dialer, this,  HttpStateData::readReply));
1411
1420
    }
1412
1421
}
1413
1422
 
1450
1459
     * request bodies.
1451
1460
     */
1452
1461
    typedef CommCbMemFunT<HttpStateData, CommTimeoutCbParams> TimeoutDialer;
1453
 
    AsyncCall::Pointer timeoutCall =  asyncCall(11, 5, "HttpStateData::httpTimeout",
1454
 
                                      TimeoutDialer(this,&HttpStateData::httpTimeout));
 
1462
    AsyncCall::Pointer timeoutCall =  JobCallback(11, 5,
 
1463
                                      TimeoutDialer, this, HttpStateData::httpTimeout);
1455
1464
 
1456
1465
    commSetTimeout(fd, Config.Timeout.read, timeoutCall);
1457
1466
 
1491
1500
                                      HttpRequest * orig_request,
1492
1501
                                      StoreEntry * entry,
1493
1502
                                      HttpHeader * hdr_out,
1494
 
                                      http_state_flags flags)
 
1503
                                      const http_state_flags flags)
1495
1504
{
1496
1505
    /* building buffer for complex strings */
1497
1506
#define BBUF_SZ (MAX_URL+32)
1720
1729
 
1721
1730
    /* maybe append Connection: keep-alive */
1722
1731
    if (flags.keepalive) {
1723
 
        if (flags.proxying) {
1724
 
            hdr_out->putStr(HDR_PROXY_CONNECTION, "keep-alive");
1725
 
        } else {
1726
 
            hdr_out->putStr(HDR_CONNECTION, "keep-alive");
1727
 
        }
 
1732
        hdr_out->putStr(HDR_CONNECTION, "keep-alive");
1728
1733
    }
1729
1734
 
1730
1735
    /* append Front-End-Https */
1773
1778
    case HDR_TE:                  /** \par TE: */
1774
1779
    case HDR_KEEP_ALIVE:          /** \par Keep-Alive: */
1775
1780
    case HDR_PROXY_AUTHENTICATE:  /** \par Proxy-Authenticate: */
1776
 
    case HDR_TRAILERS:            /** \par Trailers: */
 
1781
    case HDR_TRAILER:             /** \par Trailer: */
1777
1782
    case HDR_UPGRADE:             /** \par Upgrade: */
1778
1783
    case HDR_TRANSFER_ENCODING:   /** \par Transfer-Encoding: */
1779
1784
        break;
1870
1875
 
1871
1876
        break;
1872
1877
 
1873
 
    case HDR_PROXY_CONNECTION:
 
1878
    case HDR_PROXY_CONNECTION: // SHOULD ignore. But doing so breaks things.
 
1879
        break;
1874
1880
 
1875
1881
    case HDR_X_FORWARDED_FOR:
1876
1882
 
1877
1883
    case HDR_CACHE_CONTROL:
1878
 
        /** \par Proxy-Connaction:, X-Forwarded-For:, Cache-Control:
 
1884
        /** \par X-Forwarded-For:, Cache-Control:
1879
1885
         * handled specially by Squid, so leave off for now.
1880
1886
         * append these after the loop if needed */
1881
1887
        break;
1934
1940
HttpStateData::buildRequestPrefix(HttpRequest * aRequest,
1935
1941
                                  HttpRequest * original_request,
1936
1942
                                  StoreEntry * sentry,
1937
 
                                  MemBuf * mb,
1938
 
                                  http_state_flags stateFlags)
 
1943
                                  MemBuf * mb)
1939
1944
{
1940
1945
    const int offset = mb->size;
1941
1946
    HttpVersion httpver(1,1);
1947
1952
    {
1948
1953
        HttpHeader hdr(hoRequest);
1949
1954
        Packer p;
1950
 
        httpBuildRequestHeader(aRequest, original_request, sentry, &hdr, stateFlags);
 
1955
        httpBuildRequestHeader(aRequest, original_request, sentry, &hdr, flags);
1951
1956
 
1952
1957
        if (aRequest->flags.pinned && aRequest->flags.connection_auth)
1953
1958
            aRequest->flags.auth_sent = 1;
1979
1984
    }
1980
1985
 
1981
1986
    typedef CommCbMemFunT<HttpStateData, CommTimeoutCbParams> TimeoutDialer;
1982
 
    AsyncCall::Pointer timeoutCall =  asyncCall(11, 5, "HttpStateData::httpTimeout",
1983
 
                                      TimeoutDialer(this,&HttpStateData::httpTimeout));
 
1987
    AsyncCall::Pointer timeoutCall =  JobCallback(11, 5,
 
1988
                                      TimeoutDialer, this, HttpStateData::httpTimeout);
1984
1989
    commSetTimeout(fd, Config.Timeout.lifetime, timeoutCall);
1985
1990
    flags.do_next_read = 1;
1986
1991
    maybeReadVirginBody();
1989
1994
        if (!startRequestBodyFlow()) // register to receive body data
1990
1995
            return false;
1991
1996
        typedef CommCbMemFunT<HttpStateData, CommIoCbParams> Dialer;
1992
 
        Dialer dialer(this, &HttpStateData::sentRequestBody);
1993
 
        requestSender = asyncCall(11,5, "HttpStateData::sentRequestBody", dialer);
 
1997
        requestSender = JobCallback(11,5,
 
1998
                                    Dialer, this, HttpStateData::sentRequestBody);
1994
1999
    } else {
1995
2000
        assert(!requestBodySource);
1996
2001
        typedef CommCbMemFunT<HttpStateData, CommIoCbParams> Dialer;
1997
 
        Dialer dialer(this, &HttpStateData::sendComplete);
1998
 
        requestSender = asyncCall(11,5, "HttpStateData::SendComplete", dialer);
 
2002
        requestSender = JobCallback(11,5,
 
2003
                                    Dialer, this,  HttpStateData::sendComplete);
1999
2004
    }
2000
2005
 
2001
2006
    if (_peer != NULL) {
2035
2040
    }
2036
2041
 
2037
2042
    mb.init();
2038
 
    buildRequestPrefix(request, orig_request, entry, &mb, flags);
 
2043
    buildRequestPrefix(request, orig_request, entry, &mb);
2039
2044
    debugs(11, 6, "httpSendRequest: FD " << fd << ":\n" << mb.buf);
2040
2045
    comm_write_mbuf(fd, &mb, requestSender);
2041
2046
 
2088
2093
            }
2089
2094
 
2090
2095
            typedef CommCbMemFunT<HttpStateData, CommIoCbParams> Dialer;
2091
 
            Dialer dialer(this, &HttpStateData::sendComplete);
2092
 
            AsyncCall::Pointer call= asyncCall(11,5, "HttpStateData::SendComplete", dialer);
 
2096
            AsyncCall::Pointer call = JobCallback(11,5,
 
2097
                                                  Dialer, this, HttpStateData::sendComplete);
2093
2098
            comm_write(fd, "\r\n", 2, call);
2094
2099
        }
2095
2100
        return;