View | Details | Raw Unified | Return to bug 54102
Collapse All | Expand All

(-)docs/manual/mod/mod_proxy.xml (+5 lines)
Lines 1143-1148 Link Here
1143
        without considering the retry parameter of each worker. In this case
1143
        without considering the retry parameter of each worker. In this case
1144
        set to <code>Off</code>.
1144
        set to <code>Off</code>.
1145
    </td></tr>
1145
    </td></tr>
1146
    <tr><td>autoroute</td>
1147
        <td></td>
1148
        <td>Same application server send there route id within the response header.
1149
        The actual worker route id changed to the value of the here defined response field.
1150
    </td></tr>
1146
1151
1147
    </table>
1152
    </table>
1148
    <p>A sample balancer setup</p>
1153
    <p>A sample balancer setup</p>
(-)modules/proxy/mod_proxy_balancer.c (-1 / +70 lines)
Lines 614-619 Link Here
614
                  "%s: worker (%s) rewritten to %s",
614
                  "%s: worker (%s) rewritten to %s",
615
                  (*balancer)->s->name, (*worker)->s->name, *url);
615
                  (*balancer)->s->name, (*worker)->s->name, *url);
616
616
617
    /* store autoroute fieldname in notes for the output filter */
618
    if ((*balancer)->s->autoroute[0] != '\0') {
619
        apr_table_set(r->notes, "proxy-balancer-ar-field", (*balancer)->s->autoroute);
620
    }
621
    
617
    return access_status;
622
    return access_status;
618
}
623
}
619
624
Lines 632-637 Link Here
632
        return HTTP_INTERNAL_SERVER_ERROR;
637
        return HTTP_INTERNAL_SERVER_ERROR;
633
    }
638
    }
634
639
640
    /* set new route id */
641
    const char *new_route = apr_table_get(r->notes, "proxy-balancer-ar-newroute");
642
    if (new_route != NULL) {
643
        /* update route id */
644
        if (strcmp(worker->s->route, new_route) != 0) {
645
            if (strlen(new_route) >= PROXY_WORKER_MAX_ROUTE_SIZE) {
646
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(99999)
647
                              "%s %s: route length must be < 64 characters", 
648
                              balancer->s->name, worker->s->name);
649
            }
650
            else {
651
                PROXY_STRNCPY(worker->s->route, new_route);
652
                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(99999)
653
                              "%s: new route id (%s) for worker (%s)", 
654
                              balancer->s->name, worker->s->name, new_route);
655
            }
656
        }
657
    }
658
    
635
    if (!apr_is_empty_array(balancer->errstatuses)) {
659
    if (!apr_is_empty_array(balancer->errstatuses)) {
636
        int i;
660
        int i;
637
        for (i = 0; i < balancer->errstatuses->nelts; i++) {
661
        for (i = 0; i < balancer->errstatuses->nelts; i++) {
Lines 1136-1141 Link Here
1136
                }
1160
                }
1137
            }
1161
            }
1138
        }
1162
        }
1163
        if ((val = apr_table_get(params, "b_autoroute")) && *val) {
1164
            if (strlen(val) < (sizeof(bsel->s->autoroute)-1)) {
1165
                if (*val == '-' && *(val+1) == '\0')
1166
                    *bsel->s->autoroute = '\0';
1167
                else
1168
                    PROXY_STRNCPY(bsel->s->autoroute, val);
1169
            }
1170
        }
1139
        if ((val = apr_table_get(params, "b_wyes")) &&
1171
        if ((val = apr_table_get(params, "b_wyes")) &&
1140
            (*val == '1' && *(val+1) == '\0') &&
1172
            (*val == '1' && *(val+1) == '\0') &&
1141
            (val = apr_table_get(params, "b_nwrkr"))) {
1173
            (val = apr_table_get(params, "b_nwrkr"))) {
Lines 1233-1238 Link Here
1233
            ap_rprintf(r,
1265
            ap_rprintf(r,
1234
                       "      <httpd:timeout>%" APR_TIME_T_FMT "</httpd:timeout>",
1266
                       "      <httpd:timeout>%" APR_TIME_T_FMT "</httpd:timeout>",
1235
                       apr_time_sec(balancer->s->timeout));
1267
                       apr_time_sec(balancer->s->timeout));
1268
            if (balancer->s->autoroute) {
1269
                ap_rprintf(r,
1270
                           "      <httpd:autoroute>%s</httpd:autoroute>",
1271
                           balancer->s->autoroute);
1272
            }
1236
            if (balancer->s->max_attempts_set) {
1273
            if (balancer->s->max_attempts_set) {
1237
                ap_rprintf(r,
1274
                ap_rprintf(r,
1238
                           "      <httpd:maxattempts>%d</httpd:maxattempts>\n",
1275
                           "      <httpd:maxattempts>%d</httpd:maxattempts>\n",
Lines 1443-1449 Link Here
1443
                      "'>", NULL);
1480
                      "'>", NULL);
1444
            ap_rvputs(r, balancer->s->name, "</a> [",balancer->s->sname, "]</h3>\n", NULL);
1481
            ap_rvputs(r, balancer->s->name, "</a> [",balancer->s->sname, "]</h3>\n", NULL);
1445
            ap_rputs("\n\n<table><tr>"
1482
            ap_rputs("\n\n<table><tr>"
1446
                "<th>MaxMembers</th><th>StickySession</th><th>DisableFailover</th><th>Timeout</th><th>FailoverAttempts</th><th>Method</th>"
1483
                "<th>MaxMembers</th><th>StickySession</th><th>DisableFailover</th><th>Timeout</th><th>AutoRoute</th><th>FailoverAttempts</th><th>Method</th>"
1447
                "<th>Path</th><th>Active</th></tr>\n<tr>", r);
1484
                "<th>Path</th><th>Active</th></tr>\n<tr>", r);
1448
            /* the below is a safe cast, since the number of slots total will
1485
            /* the below is a safe cast, since the number of slots total will
1449
             * never be more than max_workers, which is restricted to int */
1486
             * never be more than max_workers, which is restricted to int */
Lines 1465-1470 Link Here
1465
                       balancer->s->sticky_force ? "On" : "Off");
1502
                       balancer->s->sticky_force ? "On" : "Off");
1466
            ap_rprintf(r, "</td><td>%" APR_TIME_T_FMT "</td>",
1503
            ap_rprintf(r, "</td><td>%" APR_TIME_T_FMT "</td>",
1467
                apr_time_sec(balancer->s->timeout));
1504
                apr_time_sec(balancer->s->timeout));
1505
            ap_rprintf(r, "<td>%s</td>\n",
1506
                       *balancer->s->autoroute == '\0' ? "(None)" : balancer->s->autoroute);
1468
            ap_rprintf(r, "<td>%d</td>\n", balancer->s->max_attempts);
1507
            ap_rprintf(r, "<td>%d</td>\n", balancer->s->max_attempts);
1469
            ap_rprintf(r, "<td>%s</td>\n",
1508
            ap_rprintf(r, "<td>%s</td>\n",
1470
                       balancer->s->lbpname);
1509
                       balancer->s->lbpname);
Lines 1586-1591 Link Here
1586
                ap_rvputs(r, "value ='", bsel->s->sticky, NULL);
1625
                ap_rvputs(r, "value ='", bsel->s->sticky, NULL);
1587
            }
1626
            }
1588
            ap_rputs("'>&nbsp;&nbsp;&nbsp;&nbsp;(Use '-' to delete)</td></tr>\n", r);
1627
            ap_rputs("'>&nbsp;&nbsp;&nbsp;&nbsp;(Use '-' to delete)</td></tr>\n", r);
1628
            ap_rputs("<tr><td>AutoRoute</td>", r);
1629
            ap_rprintf(r, "<td><input name='b_autoroute' id='b_autoroute' size=64 type=text value='%s'>&nbsp;&nbsp;&nbsp;&nbsp;(Use '-' to delete)</td></tr>",
1630
                       bsel->s->autoroute);
1589
            if (storage->num_free_slots(bsel->wslot) != 0) {
1631
            if (storage->num_free_slots(bsel->wslot) != 0) {
1590
                ap_rputs("<tr><td>Add New Worker:</td><td><input name='b_nwrkr' id='b_nwrkr' size=32 type=text>"
1632
                ap_rputs("<tr><td>Add New Worker:</td><td><input name='b_nwrkr' id='b_nwrkr' size=32 type=text>"
1591
                         "&nbsp;&nbsp;&nbsp;&nbsp;Are you sure? <input name='b_wyes' id='b_wyes' type=checkbox value='1'>"
1633
                         "&nbsp;&nbsp;&nbsp;&nbsp;Are you sure? <input name='b_wyes' id='b_wyes' type=checkbox value='1'>"
Lines 1643-1648 Link Here
1643
1685
1644
}
1686
}
1645
1687
1688
static apr_status_t proxy_balancer_fixup_headers_out(ap_filter_t *f,
1689
                                             apr_bucket_brigade *in)
1690
{
1691
    /* copy new route id to notes, and remove it from response */
1692
    const char *field;
1693
    if ((field = apr_table_get(f->r->notes, "proxy-balancer-ar-field")) != NULL) {
1694
        const char *value;
1695
        if ((value = apr_table_get(f->r->headers_out, field)) != NULL) {
1696
            apr_table_set( f->r->notes, "proxy-balancer-ar-newroute", value);
1697
            apr_table_unset( f->r->headers_out, field);
1698
        }
1699
    }
1700
    
1701
    /* remove ourselves from the filter chain */
1702
    /* send the data up the stack */
1703
    ap_remove_output_filter(f);
1704
    return ap_pass_brigade(f->next,in);
1705
}
1706
1707
static void proxy_balancer_insert_output_filter(request_rec *r)
1708
{
1709
    ap_add_output_filter("FIXUP_PROXY_BALANCER_OUT", NULL, r, r->connection);
1710
}
1711
1646
static void ap_proxy_balancer_register_hook(apr_pool_t *p)
1712
static void ap_proxy_balancer_register_hook(apr_pool_t *p)
1647
{
1713
{
1648
    /* Only the mpm_winnt has child init hook handler.
1714
    /* Only the mpm_winnt has child init hook handler.
Lines 1655-1663 Link Here
1655
    ap_hook_pre_config(balancer_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
1721
    ap_hook_pre_config(balancer_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
1656
    ap_hook_handler(balancer_handler, NULL, NULL, APR_HOOK_FIRST);
1722
    ap_hook_handler(balancer_handler, NULL, NULL, APR_HOOK_FIRST);
1657
    ap_hook_child_init(balancer_child_init, aszPred, NULL, APR_HOOK_MIDDLE);
1723
    ap_hook_child_init(balancer_child_init, aszPred, NULL, APR_HOOK_MIDDLE);
1724
    ap_hook_insert_filter(proxy_balancer_insert_output_filter, NULL, NULL, APR_HOOK_FIRST);
1658
    proxy_hook_pre_request(proxy_balancer_pre_request, NULL, NULL, APR_HOOK_FIRST);
1725
    proxy_hook_pre_request(proxy_balancer_pre_request, NULL, NULL, APR_HOOK_FIRST);
1659
    proxy_hook_post_request(proxy_balancer_post_request, NULL, NULL, APR_HOOK_FIRST);
1726
    proxy_hook_post_request(proxy_balancer_post_request, NULL, NULL, APR_HOOK_FIRST);
1660
    proxy_hook_canon_handler(proxy_balancer_canon, NULL, NULL, APR_HOOK_FIRST);
1727
    proxy_hook_canon_handler(proxy_balancer_canon, NULL, NULL, APR_HOOK_FIRST);
1728
    ap_register_output_filter("FIXUP_PROXY_BALANCER_OUT", proxy_balancer_fixup_headers_out,
1729
                              NULL, AP_FTYPE_CONTENT_SET);
1661
}
1730
}
1662
1731
1663
AP_DECLARE_MODULE(proxy_balancer) = {
1732
AP_DECLARE_MODULE(proxy_balancer) = {
(-)modules/proxy/proxy_util.c (+2 lines)
Lines 1185-1190 Link Here
1185
    bshared->sticky_separator = '.';
1185
    bshared->sticky_separator = '.';
1186
    *bshared->nonce = PROXY_UNSET_NONCE;  /* impossible valid input */
1186
    *bshared->nonce = PROXY_UNSET_NONCE;  /* impossible valid input */
1187
1187
1188
    bshared->autoroute[0] = '\0';
1189
    
1188
    (*balancer)->s = bshared;
1190
    (*balancer)->s = bshared;
1189
    (*balancer)->sconf = conf;
1191
    (*balancer)->sconf = conf;
1190
1192
(-)modules/proxy/mod_proxy.c (+5 lines)
Lines 407-412 Link Here
407
        else
407
        else
408
            return "forcerecovery must be On|Off";
408
            return "forcerecovery must be On|Off";
409
    }
409
    }
410
    else if (!strcasecmp(key, "autoroute")) {
411
        if (strlen(val) > (PROXY_BALANCER_AUTOROUTE_FIELD_SIZE-1))
412
            return "autoroute length must be < 64 characters";
413
        PROXY_STRNCPY(balancer->s->autoroute, val);
414
    }
410
    else {
415
    else {
411
        return "unknown Balancer parameter";
416
        return "unknown Balancer parameter";
412
    }
417
    }
(-)modules/proxy/mod_proxy.h (+3 lines)
Lines 310-315 Link Here
310
#define PROXY_BALANCER_MAX_HOSTNAME_SIZE PROXY_WORKER_MAX_HOSTNAME_SIZE
310
#define PROXY_BALANCER_MAX_HOSTNAME_SIZE PROXY_WORKER_MAX_HOSTNAME_SIZE
311
#define PROXY_BALANCER_MAX_STICKY_SIZE  64
311
#define PROXY_BALANCER_MAX_STICKY_SIZE  64
312
312
313
#define PROXY_BALANCER_AUTOROUTE_FIELD_SIZE  64
314
313
#define PROXY_MAX_PROVIDER_NAME_SIZE    16
315
#define PROXY_MAX_PROVIDER_NAME_SIZE    16
314
316
315
#define PROXY_STRNCPY(dst, src) ap_proxy_strncpy((dst), (src), (sizeof(dst)))
317
#define PROXY_STRNCPY(dst, src) ap_proxy_strncpy((dst), (src), (sizeof(dst)))
Lines 414-419 Link Here
414
    char      sname[PROXY_BALANCER_MAX_NAME_SIZE];
416
    char      sname[PROXY_BALANCER_MAX_NAME_SIZE];
415
    char      vpath[PROXY_BALANCER_MAX_ROUTE_SIZE];
417
    char      vpath[PROXY_BALANCER_MAX_ROUTE_SIZE];
416
    char      vhost[PROXY_BALANCER_MAX_HOSTNAME_SIZE];
418
    char      vhost[PROXY_BALANCER_MAX_HOSTNAME_SIZE];
419
    char      autoroute[PROXY_BALANCER_AUTOROUTE_FIELD_SIZE]; 
417
    apr_interval_time_t timeout;  /* Timeout for waiting on free connection */
420
    apr_interval_time_t timeout;  /* Timeout for waiting on free connection */
418
    apr_time_t      wupdated;     /* timestamp of last change to workers list */
421
    apr_time_t      wupdated;     /* timestamp of last change to workers list */
419
    int             max_attempts;     /* Number of attempts before failing */
422
    int             max_attempts;     /* Number of attempts before failing */

Return to bug 54102