~ubuntu-branches/ubuntu/intrepid/squid/intrepid

« back to all changes in this revision

Viewing changes to src/http.c

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2008-06-18 12:09:23 UTC
  • mfrom: (1.1.14 upstream)
  • Revision ID: james.westby@ubuntu.com-20080618120923-ewllt4kt92ldtvbe
Tags: 2.7.STABLE2-2ubuntu1
* Merge from debian unstable, remaining changes:
  - 99-ubuntu-ssl-cert-snakeoil:
    + src/cf.data.pre:
      * Add reference to snakeoil /etc/ssl
  - debian/control
    + Add ssl-cert to Depends to bring in snakeoil certificates.
    + Modify maintainer value to match Debian-Maintainer-Field spec.
  - debian/squid.rc
    - Use squid -k to reload the squid confiration. (LP: #204474)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
2
/*
3
 
 * $Id: http.c,v 1.419.2.12 2008/04/02 01:03:47 hno Exp $
 
3
 * $Id: http.c,v 1.439.2.4 2008/05/27 12:49:39 hno Exp $
4
4
 *
5
5
 * DEBUG: section 11    Hypertext Transfer Protocol (HTTP)
6
6
 * AUTHOR: Harvest Derived
131
131
    storeNegativeCache(entry);
132
132
    if (EBIT_TEST(entry->flags, ENTRY_CACHABLE))
133
133
        storeSetPublicKey(entry);
 
134
    if (entry->expires <= squid_curtime)
 
135
        storeRelease(entry);
134
136
}
135
137
 
136
138
static void
312
314
    case HTTP_FORBIDDEN:
313
315
    case HTTP_NOT_FOUND:
314
316
    case HTTP_METHOD_NOT_ALLOWED:
315
 
    case HTTP_REQUEST_URI_TOO_LARGE:
 
317
    case HTTP_REQUEST_URI_TOO_LONG:
316
318
    case HTTP_INTERNAL_SERVER_ERROR:
317
319
    case HTTP_NOT_IMPLEMENTED:
318
320
    case HTTP_BAD_GATEWAY:
472
474
    /* Parse headers into reply structure */
473
475
    /* what happens if we fail to parse here? */
474
476
    httpReplyParse(reply, httpState->reply_hdr.buf, hdr_size);
 
477
    done = hdr_size - old_size;
 
478
    /* Skip 1xx messages for now. Advertised in Via as an internal 1.0 hop */
 
479
    if (reply->sline.status >= 100 && reply->sline.status < 200) {
 
480
        memBufClean(&httpState->reply_hdr);
 
481
        httpReplyReset(reply);
 
482
        httpState->reply_hdr_state = 0;
 
483
        ctx_exit(ctx);
 
484
        if (done < size)
 
485
            return done + httpProcessReplyHeader(httpState, buf + done, size - done);
 
486
        else
 
487
            return done;
 
488
    }
475
489
    storeAppend(entry, httpState->reply_hdr.buf, hdr_size);
476
 
    done = hdr_size - old_size;
477
490
    if (reply->sline.status >= HTTP_INVALID_HEADER) {
478
491
        debug(11, 3) ("httpProcessReplyHeader: Non-HTTP-compliant header: '%s'\n", httpState->reply_hdr.buf);
479
492
        memBufClean(&httpState->reply_hdr);
530
543
        if (strBuf(httpState->orig_request->vary_encoding))
531
544
            entry->mem_obj->vary_encoding = xstrdup(strBuf(httpState->orig_request->vary_encoding));
532
545
    }
 
546
    if (entry->mem_obj->old_entry)
 
547
        EBIT_CLR(entry->mem_obj->old_entry->flags, REFRESH_FAILURE);
533
548
    switch (httpCachableReply(httpState)) {
534
549
    case 1:
535
550
        httpMakePublic(entry);
538
553
        httpMakePrivate(entry);
539
554
        break;
540
555
    case -1:
541
 
        if (Config.negativeTtl > 0)
542
 
            httpCacheNegatively(entry);
543
 
        else
544
 
            httpMakePrivate(entry);
 
556
        httpCacheNegatively(entry);
545
557
        break;
546
558
    default:
547
559
        assert(0);
749
761
    if (len > 0) {
750
762
        debug(11, Config.onoff.relaxed_header_parser <= 0 || keep_alive ? 1 : 2)
751
763
            ("httpReadReply: Excess data from \"%s %s\"\n",
752
 
            RequestMethodStr[orig_request->method],
 
764
            RequestMethods[orig_request->method].str,
753
765
            storeUrl(entry));
754
766
        comm_close(fd);
755
767
        return;
769
781
     * connection.
770
782
     */
771
783
    if (!httpState->flags.request_sent) {
772
 
        debug(11, 1) ("httpReadReply: Request not yet fully sent \"%s %s\"\n",
773
 
            RequestMethodStr[orig_request->method],
 
784
        debug(11, 1) ("httpAppendBody: Request not yet fully sent \"%s %s\"\n",
 
785
            RequestMethods[orig_request->method].str,
774
786
            storeUrl(entry));
775
787
        keep_alive = 0;
776
788
    }
806
818
            if (httpState->peer->options.originserver)
807
819
                pconnPush(fd, httpState->peer->name, httpState->peer->http_port, httpState->orig_request->host, client_addr, client_port);
808
820
            else
809
 
                pconnPush(fd, httpState->peer->name, httpState->peer->http_port, NULL, client_addr, client_port);
 
821
                pconnPush(fd, httpState->peer->name, httpState->peer->http_port, "*", client_addr, client_port);
810
822
        } else {
811
823
            pconnPush(fd, request->host, request->port, NULL, client_addr, client_port);
812
824
        }
924
936
        return;
925
937
    } else {
926
938
        if (httpState->reply_hdr_state < 2) {
927
 
            /* Temporarily buffer the entry. Main purpose is to ensure it gets
928
 
             * flushed to the client side when the headers is complete as
929
 
             * ENTRY_HDR_WAIT may delay the callback. It's flushed by
 
939
            /* Temporarily buffer the entry. Main purpose is to ensure it gets flushed to the client side
 
940
             * when the headers is complete as ENTRY_HDR_WAIT may delay the callback. It's flushed by
930
941
             * httpAppendBody().
931
942
             */
932
943
            storeBuffer(entry);
951
962
                    MemBuf mb;
952
963
                    HttpReply *reply = entry->mem_obj->reply;
953
964
                    httpReplyReset(reply);
954
 
                    httpBuildVersion(&reply->sline.version, 1, 0);
 
965
                    httpBuildVersion(&reply->sline.version, 0, 9);
955
966
                    reply->sline.status = HTTP_OK;
956
967
                    httpHeaderPutTime(&reply->header, HDR_DATE, squid_curtime);
957
968
                    mb = httpReplyPack(reply);
1100
1111
             * authentication forwarding is explicitly enabled
1101
1112
             */
1102
1113
            if (flags.proxying && orig_request->peer_login && strcmp(orig_request->peer_login, "PASS") == 0) {
1103
 
                httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
 
1114
                httpHeaderAddClone(hdr_out, e);
1104
1115
                if (request->flags.connection_proxy_auth)
1105
1116
                    request->flags.pinned = 1;
1106
1117
            }
1109
1120
            /* Pass on WWW authentication.
1110
1121
             */
1111
1122
            if (!flags.originpeer) {
1112
 
                httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
 
1123
                httpHeaderAddClone(hdr_out, e);
1113
1124
                if (orig_request->flags.connection_auth)
1114
1125
                    orig_request->flags.pinned = 1;
1115
1126
            } else {
1117
1128
                 * (see also below for proxy->server authentication)
1118
1129
                 */
1119
1130
                if (orig_request->peer_login && (strcmp(orig_request->peer_login, "PASS") == 0 || strcmp(orig_request->peer_login, "PROXYPASS") == 0)) {
1120
 
                    httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
 
1131
                    httpHeaderAddClone(hdr_out, e);
1121
1132
                    if (orig_request->flags.connection_auth)
1122
1133
                        orig_request->flags.pinned = 1;
1123
1134
                }
1133
1144
            if (orig_request->peer_domain)
1134
1145
                httpHeaderPutStr(hdr_out, HDR_HOST, orig_request->peer_domain);
1135
1146
            else if (request->flags.redirected && !Config.onoff.redir_rewrites_host)
1136
 
                httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
 
1147
                httpHeaderAddClone(hdr_out, e);
1137
1148
            else {
1138
1149
                /* use port# only if not default */
1139
1150
                if (orig_request->port == urlDefaultPort(orig_request->protocol)) {
1148
1159
            /* append unless we added our own;
1149
1160
             * note: at most one client's ims header can pass through */
1150
1161
            if (!httpHeaderHas(hdr_out, HDR_IF_MODIFIED_SINCE))
1151
 
                httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
 
1162
                if (!Config.onoff.ignore_ims_on_miss || !orig_request->flags.cachable || orig_request->flags.auth)
 
1163
                    httpHeaderAddClone(hdr_out, e);
1152
1164
            break;
1153
1165
        case HDR_IF_NONE_MATCH:
1154
 
            /* append unless we added our own;
1155
 
             * note: at most one client's ims header can pass through */
 
1166
            /* append unless ignore_ims_on_miss is in effect */
1156
1167
            if (!httpHeaderHas(hdr_out, HDR_IF_NONE_MATCH))
1157
 
                httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
 
1168
                if (!Config.onoff.ignore_ims_on_miss || !orig_request->flags.cachable || orig_request->flags.auth)
 
1169
                    httpHeaderAddClone(hdr_out, e);
1158
1170
            break;
1159
1171
        case HDR_MAX_FORWARDS:
1160
1172
            if (orig_request->method == METHOD_TRACE) {
1166
1178
            break;
1167
1179
        case HDR_X_FORWARDED_FOR:
1168
1180
            if (!opt_forwarded_for)
1169
 
                httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
 
1181
                httpHeaderAddClone(hdr_out, e);
1170
1182
            break;
1171
1183
        case HDR_RANGE:
1172
1184
        case HDR_IF_RANGE:
1173
1185
        case HDR_REQUEST_RANGE:
1174
1186
            if (!we_do_ranges)
1175
 
                httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
 
1187
                httpHeaderAddClone(hdr_out, e);
1176
1188
            break;
1177
1189
        case HDR_VIA:
1178
1190
            /* If Via is disabled then forward any received header as-is */
1179
1191
            if (!Config.onoff.via)
1180
 
                httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
 
1192
                httpHeaderAddClone(hdr_out, e);
1181
1193
            break;
1182
1194
        case HDR_CONNECTION:
1183
1195
        case HDR_KEEP_ALIVE:
1188
1200
        case HDR_TRANSFER_ENCODING:
1189
1201
        case HDR_UPGRADE:
1190
1202
        case HDR_PROXY_CONNECTION:
1191
 
        case HDR_EXPECT:
1192
1203
            /* hop-by-hop headers. Don't forward */
1193
1204
            break;
1194
1205
        case HDR_CACHE_CONTROL:
1196
1207
            break;
1197
1208
        case HDR_FRONT_END_HTTPS:
1198
1209
            if (!flags.front_end_https)
1199
 
                httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
 
1210
                httpHeaderAddClone(hdr_out, e);
1200
1211
            break;
1201
1212
        default:
1202
1213
            /* pass on all other header fields */
1203
 
            httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
 
1214
            httpHeaderAddClone(hdr_out, e);
1204
1215
        }
1205
1216
    }
1206
1217
 
1211
1222
            orig_request->http_ver.major,
1212
1223
            orig_request->http_ver.minor, ThisCache);
1213
1224
        strListAdd(&strVia, bbuf, ',');
 
1225
        if (flags.http11)
 
1226
            strListAdd(&strVia, "1.0 internal", ',');
1214
1227
        httpHeaderPutStr(hdr_out, HDR_VIA, strBuf(strVia));
1215
1228
        stringClean(&strVia);
1216
1229
    }
1362
1375
    http_state_flags flags)
1363
1376
{
1364
1377
    const int offset = mb->size;
1365
 
    memBufPrintf(mb, "%s %s HTTP/1.0\r\n",
1366
 
        RequestMethodStr[request->method],
1367
 
        strLen(request->urlpath) ? strBuf(request->urlpath) : "/");
 
1378
    memBufPrintf(mb, "%s %s HTTP/1.%d\r\n",
 
1379
        RequestMethods[request->method].str,
 
1380
        strLen(request->urlpath) ? strBuf(request->urlpath) : "/",
 
1381
        flags.http11);
1368
1382
    /* build and pack headers */
1369
1383
    {
1370
1384
        HttpHeader hdr;
1431
1445
            httpState->flags.only_if_cached = 1;
1432
1446
        httpState->flags.front_end_https = httpState->peer->front_end_https;
1433
1447
    }
 
1448
    if (httpState->peer)
 
1449
        httpState->flags.http11 = httpState->peer->options.http11;
 
1450
    else
 
1451
        httpState->flags.http11 = Config.onoff.server_http11;
1434
1452
    memBufDefInit(&mb);
1435
1453
    httpBuildRequestPrefix(req,
1436
1454
        httpState->orig_request,
1451
1469
    request_t *proxy_req;
1452
1470
    request_t *orig_req = fwd->request;
1453
1471
    debug(11, 3) ("httpStart: \"%s %s\"\n",
1454
 
        RequestMethodStr[orig_req->method],
 
1472
        RequestMethods[orig_req->method].str,
1455
1473
        storeUrl(fwd->entry));
1456
1474
    httpState = cbdataAlloc(HttpStateData);
1457
1475
    storeLockObject(fwd->entry);
1509
1527
httpSendRequestEntryDone(int fd, void *data)
1510
1528
{
1511
1529
    HttpStateData *httpState = data;
1512
 
    aclCheck_t ch;
1513
1530
    debug(11, 5) ("httpSendRequestEntryDone: FD %d\n",
1514
1531
        fd);
1515
 
    memset(&ch, '\0', sizeof(ch));
1516
 
    ch.request = httpState->request;
1517
1532
    if (!Config.accessList.brokenPosts) {
1518
1533
        debug(11, 5) ("httpSendRequestEntryDone: No brokenPosts list\n");
1519
1534
        httpSendComplete(fd, NULL, 0, 0, data);
1520
 
    } else if (!aclCheckFast(Config.accessList.brokenPosts, &ch)) {
 
1535
    } else if (!aclCheckFastRequest(Config.accessList.brokenPosts, httpState->request)) {
1521
1536
        debug(11, 5) ("httpSendRequestEntryDone: didn't match brokenPosts\n");
1522
1537
        httpSendComplete(fd, NULL, 0, 0, data);
1523
1538
    } else {
1543
1558
    if (size > 0) {
1544
1559
        if (httpState->reply_hdr_state >= 2 && !httpState->flags.abuse_detected) {
1545
1560
            httpState->flags.abuse_detected = 1;
1546
 
            debug(11, 1) ("httpSendRequestEntryDone: Likely proxy abuse detected '%s' -> '%s'\n",
 
1561
            debug(11, 1) ("httpRequestBodyHandler: Likely proxy abuse detected '%s' -> '%s'\n",
1547
1562
                inet_ntoa(httpState->orig_request->client_addr),
1548
1563
                storeUrl(httpState->entry));
1549
1564
            if (httpState->entry->mem_obj->reply->sline.status == HTTP_INVALID_HEADER) {