]> git.pld-linux.org Git - packages/lighttpd.git/commitdiff
- r1202 DEVLE
authorElan Ruusamäe <glen@pld-linux.org>
Tue, 18 Jul 2006 14:36:48 +0000 (14:36 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    lighttpd-branch.diff -> 1.8

lighttpd-branch.diff

index 9d33e7f58115c780b2a6b799923061ede0d9180d..7f42de3b74c4f40b7a31bece54e1ce629c30e93d 100644 (file)
  LIGHTTPD_DIR=$(BUILD_DIR)/$(LIGHTTPD)
  LIGHTTPD_IPK=$(BUILD_DIR)/$(LIGHTTPD)_mipsel.ipk
 --- ../lighttpd-1.4.11/src/Makefile.am 2006-03-07 14:20:20.000000000 +0200
-+++ lighttpd-1.4.12/src/Makefile.am    2006-07-18 13:03:40.000000000 +0300
++++ lighttpd-1.4.12/src/Makefile.am    2006-07-18 17:34:32.000000000 +0300
 @@ -16,18 +16,24 @@
  else
  configparser.y: lemon
  lib_LTLIBRARIES += mod_cgi.la
  mod_cgi_la_SOURCES = mod_cgi.c 
  mod_cgi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
-@@ -158,6 +169,13 @@
+@@ -158,6 +169,14 @@
  mod_proxy_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
  mod_proxy_la_LIBADD = $(common_libadd)
  
 +lib_LTLIBRARIES += mod_proxy_core.la
 +mod_proxy_core_la_SOURCES = mod_proxy_core.c mod_proxy_core_pool.c \
-+                          mod_proxy_core_backend.c mod_proxy_core_address.c mod_proxy_core_backlog.c
++                          mod_proxy_core_backend.c mod_proxy_core_address.c \
++                          mod_proxy_core_backlog.c mod_proxy_core_rewrites.c
 +mod_proxy_core_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
-+mod_proxy_core_la_LIBADD = $(common_libadd)
++mod_proxy_core_la_LIBADD = $(common_libadd) $(PCRE_LIB)
 +
 +
  lib_LTLIBRARIES += mod_ssi.la
  mod_ssi_la_SOURCES = mod_ssi_exprparser.c mod_ssi_expr.c mod_ssi.c 
  mod_ssi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
-@@ -240,7 +258,12 @@
+@@ -240,7 +259,12 @@
        mod_ssi.h mod_ssi_expr.h inet_ntop_cache.h \
        configparser.h mod_ssi_exprparser.h \
        sys-mmap.h sys-socket.h mod_cml.h mod_cml_funcs.h \
 +      iosocket.h array-static.h \
 +      mod_proxy_core_address.h mod_proxy_core_backend.h \
 +      mod_proxy_core_backlog.h mod_proxy_core.h  \
-+      mod_proxy_core_pool.h
++      mod_proxy_core_pool.h mod_proxy_core_rewrites.h
  
  DEFS= @DEFS@ -DLIBRARY_DIR="\"$(libdir)\""
  
-@@ -267,4 +290,4 @@
+@@ -267,4 +291,4 @@
  #ajp_SOURCES = ajp.c
  
  noinst_HEADERS   = $(hdr)
        return 0;
  }
 --- ../lighttpd-1.4.11/src/mod_cgi.c   2006-02-22 15:15:10.000000000 +0200
-+++ lighttpd-1.4.12/src/mod_cgi.c      2006-07-18 13:03:40.000000000 +0300
++++ lighttpd-1.4.12/src/mod_cgi.c      2006-07-18 17:34:32.000000000 +0300
 @@ -1,21 +1,8 @@
  #include <sys/types.h>
 -#ifdef __WIN32
        if (r->size == 0) {
                r->size = 16;
                r->ptr = malloc(sizeof(*r->ptr) * r->size);
-@@ -194,321 +201,178 @@
+@@ -194,321 +201,179 @@
                r->size += 16;
                r->ptr = realloc(r->ptr, sizeof(*r->ptr) * r->size);
        }
 -      cgi_handler_ctx_free(hctx);
 -      
 +      cgi_session_free(sess);
++      sess = NULL;
 +
        /* if waitpid hasn't been called by response.c yet, do it here */
        if (pid) {
                switch(waitpid(pid, &status, WNOHANG)) {
                case 0:
                        /* not finished yet */
-@@ -519,35 +383,35 @@
+@@ -519,35 +384,35 @@
                case -1:
                        /* */
                        if (errno == EINTR) break;
                                return HANDLER_GO_ON;
                        } else {
                                log_error_write(srv, __FILE__, __LINE__, "sd", "cgi died, pid:", pid);
-@@ -555,122 +419,126 @@
+@@ -555,122 +420,126 @@
                                return HANDLER_GO_ON;
                        }
                }
        if (env->size == 0) {
                env->size = 16;
                env->ptr = malloc(env->size * sizeof(*env->ptr));
-@@ -678,45 +546,45 @@
+@@ -678,45 +547,45 @@
                env->size += 16;
                env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
        }
        /* fork, execve */
        switch (pid = fork()) {
        case 0: {
-@@ -730,44 +598,40 @@
+@@ -730,44 +599,40 @@
                char *c;
                const char *s;
                server_socket *srv_sock = con->srv_socket;
                                      (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
                                      (const void *) &(srv_sock->addr.ipv4.sin_addr),
                                      b2, sizeof(b2)-1);
-@@ -779,10 +643,12 @@
+@@ -779,10 +644,10 @@
                cgi_env_add(&env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1"));
  
                s = get_http_version_name(con->request.http_version);
 -              
-+
-+              TRACE("http-version: %s (%d)", s, con->request.http_version);
 +
                cgi_env_add(&env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
 -              
  #ifdef HAVE_IPV6
                        ntohs(srv_sock->addr.plain.sa_family == AF_INET6 ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
  #else
-@@ -790,10 +656,10 @@
+@@ -790,10 +655,10 @@
  #endif
                        );
                cgi_env_add(&env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf));
                              (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
                              (const void *) &(srv_sock->addr.ipv4.sin_addr),
                              b2, sizeof(b2)-1);
-@@ -811,15 +677,18 @@
+@@ -811,15 +676,18 @@
                cgi_env_add(&env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200"));
                if (!buffer_is_empty(con->uri.query)) {
                        cgi_env_add(&env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query));
                              (const void *) &(con->dst_addr.ipv6.sin6_addr) :
                              (const void *) &(con->dst_addr.ipv4.sin_addr),
                              b2, sizeof(b2)-1);
-@@ -828,7 +697,7 @@
+@@ -828,7 +696,7 @@
  #endif
                cgi_env_add(&env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
  
  #ifdef HAVE_IPV6
                        ntohs(con->dst_addr.plain.sa_family == AF_INET6 ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
  #else
-@@ -836,19 +705,19 @@
+@@ -836,19 +704,19 @@
  #endif
                        );
                cgi_env_add(&env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf));
                /* for valgrind */
                if (NULL != (s = getenv("LD_PRELOAD"))) {
                        cgi_env_add(&env, CONST_STR_LEN("LD_PRELOAD"), s, strlen(s));
-@@ -863,24 +732,24 @@
+@@ -863,24 +731,24 @@
                        cgi_env_add(&env, CONST_STR_LEN("SYSTEMROOT"), s, strlen(s));
                }
  #endif
                                for (j = 0; j < ds->key->used - 1; j++) {
                                        char cr = '_';
                                        if (light_isalpha(ds->key->ptr[j])) {
-@@ -893,46 +762,46 @@
+@@ -893,46 +761,46 @@
                                        p->tmp_buf->ptr[p->tmp_buf->used++] = cr;
                                }
                                p->tmp_buf->ptr[p->tmp_buf->used++] = '\0';
                if (cgi_handler->used > 1) {
                        args[i++] = cgi_handler->ptr;
                }
-@@ -942,7 +811,7 @@
+@@ -942,7 +810,7 @@
                /* search for the last / */
                if (NULL != (c = strrchr(con->physical.path->ptr, '/'))) {
                        *c = '\0';
                        /* change to the physical directory */
                        if (-1 == chdir(con->physical.path->ptr)) {
                                log_error_write(srv, __FILE__, __LINE__, "ssb", "chdir failed:", strerror(errno), con->physical.path);
-@@ -952,14 +821,14 @@
+@@ -952,14 +820,14 @@
  
                /* we don't need the client socket */
                for (i = 3; i < 256; i++) {
                /* */
                SEGFAULT();
                break;
-@@ -969,16 +838,16 @@
+@@ -969,16 +837,16 @@
                log_error_write(srv, __FILE__, __LINE__, "ss", "fork failed:", strerror(errno));
                break;
        default: {
                        assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
  
                        /* there is content to send */
-@@ -993,16 +862,16 @@
+@@ -993,16 +861,16 @@
                                                if (-1 == c->file.fd &&  /* open the file if not already open */
                                                    -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
                                                        log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
                                                                        strerror(errno), c->file.name,  c->file.fd);
  
                                                        close(from_cgi_fds[0]);
-@@ -1012,7 +881,7 @@
+@@ -1012,7 +880,7 @@
  
                                                close(c->file.fd);
                                                c->file.fd = -1;
                                                /* chunk_reset() or chunk_free() will cleanup for us */
                                        }
  
-@@ -1020,7 +889,7 @@
+@@ -1020,7 +888,7 @@
                                                switch(errno) {
                                                case ENOSPC:
                                                        con->http_status = 507;
                                                        break;
                                                default:
                                                        con->http_status = 403;
-@@ -1033,7 +902,7 @@
+@@ -1033,7 +901,7 @@
                                                switch(errno) {
                                                case ENOSPC:
                                                        con->http_status = 507;
                                                        break;
                                                default:
                                                        con->http_status = 403;
-@@ -1056,103 +925,95 @@
+@@ -1056,103 +924,95 @@
                }
  
                close(to_cgi_fds[1]);
 +              sess->remote_con = con;
 +              sess->pid = pid;
 +
++              assert(sess->sock);
++
 +              sess->sock->fd = from_cgi_fds[0];
 +              sess->sock->type = IOSOCKET_TYPE_PIPE;
 +
 +
        if (fn->used == 0) return HANDLER_GO_ON;
 -      
-+
-+      TRACE("http-version: (%d)", con->request.http_version);
 +
        mod_cgi_patch_connection(srv, con, p);
 -      
                                buffer_reset(con->physical.path);
                                return HANDLER_FINISHED;
                        }
-@@ -1160,7 +1021,7 @@
+@@ -1160,7 +1020,7 @@
                        break;
                }
        }
        return HANDLER_GO_ON;
  }
  
-@@ -1168,11 +1029,11 @@
+@@ -1168,11 +1028,11 @@
        plugin_data *p = p_d;
        size_t ndx;
        /* the trigger handle only cares about lonely PID which we have to wait for */
                switch(waitpid(p->cgi_pid.ptr[ndx], &status, WNOHANG)) {
                case 0:
                        /* not finished yet */
-@@ -1182,7 +1043,7 @@
+@@ -1182,7 +1042,7 @@
                        break;
                case -1:
                        log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno));
                        return HANDLER_ERROR;
                default:
  
-@@ -1193,96 +1054,103 @@
+@@ -1193,96 +1053,105 @@
                        } else {
                                log_error_write(srv, __FILE__, __LINE__, "s", "cgi died ?");
                        }
 +              fdevent_unregister(srv->ev, sess->sock);
 +
 +              cgi_session_free(sess);
++              sess = NULL;
 +
                con->plugin_ctx[p->id] = NULL;
 -              
 +              fdevent_unregister(srv->ev, sess->sock);
 +
 +              cgi_session_free(sess);
++              sess = NULL;
 +
                con->plugin_ctx[p->id] = NULL;
                return HANDLER_FINISHED;
        }
-@@ -1306,8 +1174,8 @@
+@@ -1306,8 +1175,8 @@
        p->init           = mod_cgi_init;
        p->cleanup        = mod_cgi_free;
        p->set_defaults   = mod_fastcgi_set_defaults;
        return 0;
  }
 --- ../lighttpd-1.4.11/src/mod_proxy_core.c    1970-01-01 03:00:00.000000000 +0300
-+++ lighttpd-1.4.12/src/mod_proxy_core.c       2006-07-18 13:03:40.000000000 +0300
-@@ -0,0 +1,1451 @@
++++ lighttpd-1.4.12/src/mod_proxy_core.c       2006-07-18 17:34:32.000000000 +0300
+@@ -0,0 +1,1709 @@
 +#include <string.h>
 +#include <stdlib.h>
 +#include <fcntl.h>
 +#include <errno.h>
++#include <ctype.h>
 +
 +#include "buffer.h"
 +#include "array.h"
 +#include "mod_proxy_core_pool.h"      
 +#include "mod_proxy_core_backend.h"
 +#include "mod_proxy_core_backlog.h"
++#include "mod_proxy_core_rewrites.h"
++
++#define CONFIG_PROXY_CORE_REWRITE_REQUEST "proxy-core.rewrite-request"
++#define CONFIG_PROXY_CORE_REWRITE_RESPONSE "proxy-core.rewrite-response"
 +
 +typedef enum {
 +      PROXY_PROTOCOL_UNSET,
 +
 +      proxy_backlog *backlog;
 +
++      proxy_rewrites *request_rewrites;
++      proxy_rewrites *response_rewrites;
++
 +      int debug;
 +
 +      proxy_balance_t balancer;
 +      buffer *protocol_buf;
 +      buffer *balance_buf;
 +
++      buffer *replace_buf;
++
 +      plugin_config **config_storage;
 +
 +      plugin_config conf;
 +
 +      p->balance_buf = buffer_init();
 +      p->protocol_buf = buffer_init();
++      p->replace_buf = buffer_init();
 +      p->backends_arr = array_init();
 +
 +      p->resp = http_response_init();
 +
 +      buffer_free(p->balance_buf);
 +      buffer_free(p->protocol_buf);
++      buffer_free(p->replace_buf);
 +      
 +      http_response_free(p->resp);
 +
 +      return HANDLER_GO_ON;
 +}
 +
++static handler_t mod_proxy_core_config_parse_rewrites(proxy_rewrites *dest, array *src, const char *config_key) {
++      data_unset *du;
++      size_t j;
++
++      if (NULL != (du = array_get_element(src, config_key))) {
++              data_array *keys = (data_array *)du;
++
++              if (keys->type != TYPE_ARRAY) {
++                      ERROR("%s = <...>", 
++                              config_key);
++
++                      return HANDLER_ERROR;
++              }
++
++              /*
++               * proxy-core.rewrite-request = (
++               *   "_uri" => ( ... ) 
++               * )
++               */
++
++              for (j = 0; j < keys->value->used; j++) {
++                      size_t k;
++                      data_array *headers = (data_array *)keys->value->data[j];
++
++                      /* keys->key should be "_uri" and the value a array of rewrite */
++                      if (headers->type != TYPE_ARRAY) {
++                              ERROR("%s = ( %s => <...> ) has to a array", 
++                                      config_key,
++                                      BUF_STR(headers->key));
++
++                              return HANDLER_ERROR;
++                      }
++
++                      TRACE("%s: header-field: %s", config_key, BUF_STR(headers->key));
++
++                      if (headers->value->used > 1) {
++                              ERROR("%s = ( %s => <...> ) has to a array with only one element", 
++                                      config_key,
++                                      BUF_STR(headers->key));
++
++                              return HANDLER_ERROR;
++
++                      }
++
++                      for (k = 0; k < headers->value->used; k++) {
++                              data_string *rewrites = (data_string *)headers->value->data[k];
++                              proxy_rewrite *rw;
++
++                              /* keys->key should be "_uri" and the value a array of rewrite */
++                              if (rewrites->type != TYPE_STRING) {
++                                      ERROR("%s = ( \"%s\" => ( \"%s\" => <value> ) ) has to a string", 
++                                              config_key,
++                                              BUF_STR(headers->key),
++                                              BUF_STR(rewrites->key));
++
++                                      return HANDLER_ERROR;
++                              }
++                      
++                              TRACE("%s: rewrites-field: %s -> %s", 
++                                              config_key, 
++                                              BUF_STR(headers->key), 
++                                              BUF_STR(rewrites->key));
++
++                              rw = proxy_rewrite_init();
++
++                              if (0 != proxy_rewrite_set_regex(rw, rewrites->key)) {
++                                      return HANDLER_ERROR;
++                              }
++                              buffer_copy_string_buffer(rw->replace, rewrites->value);
++                              buffer_copy_string_buffer(rw->match, rewrites->key);
++                              buffer_copy_string_buffer(rw->header, headers->key);
++
++                              proxy_rewrites_add(dest, rw);
++                      }
++              }
++      }
++
++      return HANDLER_GO_ON;
++}
++
++
 +SETDEFAULTS_FUNC(mod_proxy_core_set_defaults) {
 +      plugin_data *p = p_d;
 +      size_t i, j;
 +              { "proxy-core.debug",          NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
 +              { "proxy-core.balancer",       NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },      /* 2 */
 +              { "proxy-core.protocol",       NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },      /* 3 */
++              { CONFIG_PROXY_CORE_REWRITE_REQUEST, NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 4 */
++              { CONFIG_PROXY_CORE_REWRITE_RESPONSE, NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION },/* 5 */
 +              { NULL,                        NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
 +      };
 +
 +              s->protocol  = PROXY_PROTOCOL_UNSET;
 +              s->backends  = proxy_backends_init();
 +              s->backlog   = proxy_backlog_init();
++              s->response_rewrites   = proxy_rewrites_init();
++              s->request_rewrites   = proxy_rewrites_init();
 +
 +              cv[0].destination = p->backends_arr;
 +              cv[1].destination = &(s->debug);
 +                      s->protocol = di->value;
 +              }
 +
-+              backend = proxy_backend_init();
++              if (p->backends_arr->used) {
++                      backend = proxy_backend_init();
 +
-+              /* check if the backends have a valid host-name */
-+              for (j = 0; j < p->backends_arr->used; j++) {
-+                      data_string *ds = (data_string *)p->backends_arr->data[j];
++                      /* check if the backends have a valid host-name */
++                      for (j = 0; j < p->backends_arr->used; j++) {
++                              data_string *ds = (data_string *)p->backends_arr->data[j];
 +
-+                      /* the values should be ips or hostnames */
-+                      if (0 != proxy_address_pool_add_string(backend->address_pool, ds->value)) {
-+                              return HANDLER_ERROR;
++                              /* the values should be ips or hostnames */
++                              if (0 != proxy_address_pool_add_string(backend->address_pool, ds->value)) {
++                                      return HANDLER_ERROR;
++                              }
 +                      }
++
++                      proxy_backends_add(s->backends, backend);
 +              }
 +
-+              proxy_backends_add(s->backends, backend);
++              if (HANDLER_GO_ON != mod_proxy_core_config_parse_rewrites(s->request_rewrites, ca, CONFIG_PROXY_CORE_REWRITE_REQUEST)) {
++                      return HANDLER_ERROR;
++              }
++              
++              if (HANDLER_GO_ON != mod_proxy_core_config_parse_rewrites(s->response_rewrites, ca, CONFIG_PROXY_CORE_REWRITE_RESPONSE)) {
++                      return HANDLER_ERROR;
++              }
 +      }
 +
 +      return HANDLER_GO_ON;
 +      } else {
 +              /* no chunked encoding, ok, perhaps a content-length ? */
 +
-+              TRACE("content-lenght: %d", sess->content_length);
-+
 +              chunkqueue_remove_finished_chunks(raw);
 +              for (c = raw->first; c; c = c->next) {
 +                      buffer *b;
 +      return HANDLER_GO_ON;
 +}
 +
++int pcre_replace(pcre *match, buffer *replace, buffer *match_buf, buffer *result) {
++      const char *pattern = replace->ptr;
++      size_t pattern_len = replace->used - 1;
++
++# define N 10
++      int ovec[N * 3];
++      int n;
++
++      if ((n = pcre_exec(match, NULL, match_buf->ptr, match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
++              if (n != PCRE_ERROR_NOMATCH) {
++                      return n;
++              }
++      } else {
++              const char **list;
++              size_t start, end;
++              size_t k;
++
++              /* it matched */
++              pcre_get_substring_list(match_buf->ptr, ovec, n, &list);
++
++              /* search for $[0-9] */
++
++              buffer_reset(result);
++
++              start = 0; end = pattern_len;
++              for (k = 0; k < pattern_len; k++) {
++                      if ((pattern[k] == '$') &&
++                          isdigit((unsigned char)pattern[k + 1])) {
++                              /* got one */
++
++                              size_t num = pattern[k + 1] - '0';
++
++                              end = k;
++
++                              buffer_append_string_len(result, pattern + start, end - start);
++
++                              /* n is always > 0 */
++                              if (num < (size_t)n) {
++                                      buffer_append_string(result, list[num]);
++                              }
++
++                              k++;
++                              start = k + 1;
++                      }
++              }
++
++              buffer_append_string_len(result, pattern + start, pattern_len - start);
++
++              pcre_free(list);
++      }
++
++      return n;
++}
++
 +/**
 + * generate a HTTP/1.1 proxy request from the set of request-headers
 + *
 + * TODO: this is HTTP-proxy specific and will be moved moved into a separate backed
 + *
 + */
-+int proxy_get_request_chunk(server *srv, connection *con, proxy_session *sess, chunkqueue *cq) {
++int proxy_get_request_chunk(server *srv, connection *con, plugin_data *p, proxy_session *sess, chunkqueue *cq) {
 +      buffer *b;
 +      size_t i;
-+
++      
 +      b = chunkqueue_get_append_buffer(cq);
 +
 +      /* request line */
 +      buffer_copy_string(b, get_http_method_name(con->request.http_method));
 +      BUFFER_APPEND_STRING_CONST(b, " ");
 +
-+      buffer_append_string_buffer(b, con->request.uri);
++      /* check if we want to rewrite the uri */
++
++      for (i = 0; i < p->conf.request_rewrites->used; i++) {
++              proxy_rewrite *rw = p->conf.request_rewrites->ptr[i];
++
++              if (buffer_is_equal_string(rw->header, CONST_STR_LEN("_uri"))) {
++                      int ret;
++
++                      if ((ret = pcre_replace(rw->regex, rw->replace, con->request.uri, p->replace_buf)) < 0) {
++                              switch (ret) {
++                              case PCRE_ERROR_NOMATCH:
++                                      /* hmm, ok. no problem */
++                                      buffer_append_string_buffer(b, con->request.uri);
++                                      break;
++                              default:
++                                      TRACE("oops, pcre_replace failed with: %d", ret);
++                                      break;
++                              }
++                      } else {
++                              buffer_append_string_buffer(b, p->replace_buf);
++                      }
++
++                      break;
++              }
++      }
++
++      if (i == p->conf.request_rewrites->used) {
++              /* not found */
++              buffer_append_string_buffer(b, con->request.uri);
++      }
++
 +      BUFFER_APPEND_STRING_CONST(b, " HTTP/1.1\r\n");
 +
 +      for (i = 0; i < sess->request_headers->used; i++) {
 +      }
 +
 +      BUFFER_APPEND_STRING_CONST(b, "\r\n");
-+
++      
 +      return 0;
 +}
 +
 +void proxy_set_header(array *hdrs, const char *key, size_t key_len, const char *value, size_t val_len) {
 +      data_string *ds_dst;
 +
++      if (NULL != (ds_dst = (data_string *)array_get_element(hdrs, key))) {
++              buffer_copy_string_len(ds_dst->value, value, val_len);
++              return;
++      }
++
 +      if (NULL == (ds_dst = (data_string *)array_get_unused_element(hdrs, TYPE_STRING))) {
 +              ds_dst = data_string_init();
 +      }
 + * build the request-header array and call the backend specific request formater
 + * to fill the chunkqueue
 + */
-+int proxy_get_request_header(server *srv, connection *con, proxy_session *sess) {
++int proxy_get_request_header(server *srv, connection *con, plugin_data *p, proxy_session *sess) {
 +      /* request line */
 +      const char *remote_ip;
 +      size_t i;
 +      /* request header */
 +      for (i = 0; i < con->request.headers->used; i++) {
 +              data_string *ds;
++              size_t k;
 +
 +              ds = (data_string *)con->request.headers->data[i];
 +
 +              if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue;
 +              if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Keep-Alive"))) continue;
 +
-+              proxy_set_header(sess->request_headers, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
++              for (k = 0; k < p->conf.request_rewrites->used; k++) {
++                      proxy_rewrite *rw = p->conf.request_rewrites->ptr[k];
++
++                      if (buffer_is_equal(rw->header, ds->key)) {
++                              int ret;
++
++                              if ((ret = pcre_replace(rw->regex, rw->replace, ds->value, p->replace_buf)) < 0) {
++                                      switch (ret) {
++                                      case PCRE_ERROR_NOMATCH:
++                                              /* hmm, ok. no problem */
++                                              proxy_set_header(sess->request_headers, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
++                                              break;
++                                      default:
++                                              TRACE("oops, pcre_replace failed with: %d", ret);
++                                              break;
++                                      }
++                              } else {
++                                      proxy_set_header(sess->request_headers, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(p->replace_buf));
++                              }
++
++                              break;
++                      }
++              }
++
++              if (k == p->conf.request_rewrites->used) {
++                      proxy_set_header(sess->request_headers, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
++              }
 +      }
 +
-+      proxy_get_request_chunk(srv, con, sess, sess->send_raw);
++      proxy_get_request_chunk(srv, con, p, sess, sess->send_raw);
 +
 +      return 0;
 +}
 +              /* copy the http-headers */
 +              for (i = 0; i < p->resp->headers->used; i++) {
 +                      const char *ign[] = { "Status", "Connection", NULL };
-+                      size_t j;
++                      size_t j, k;
 +                      data_string *ds;
 +
 +                      data_string *header = (data_string *)p->resp->headers->data[i];
 +                      if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
 +                              ds = data_response_init();
 +                      }
++
++
 +                      buffer_copy_string_buffer(ds->key, header->key);
-+                      buffer_copy_string_buffer(ds->value, header->value);
++
++                      for (k = 0; k < p->conf.response_rewrites->used; k++) {
++                              proxy_rewrite *rw = p->conf.response_rewrites->ptr[k];
++
++                              if (buffer_is_equal(rw->header, header->key)) {
++                                      int ret;
++      
++                                      if ((ret = pcre_replace(rw->regex, rw->replace, header->value, p->replace_buf)) < 0) {
++                                              switch (ret) {
++                                              case PCRE_ERROR_NOMATCH:
++                                                      /* hmm, ok. no problem */
++                                                      buffer_append_string_buffer(ds->value, header->value);
++                                                      break;
++                                              default:
++                                                      TRACE("oops, pcre_replace failed with: %d", ret);
++                                                      break;
++                                              }
++                                      } else {
++                                              buffer_append_string_buffer(ds->value, p->replace_buf);
++                                      }
++
++                                      break;
++                              }
++                      }
++
++                      if (k == p->conf.response_rewrites->used) {
++                              buffer_copy_string_buffer(ds->value, header->value);
++                      }
 +
 +                      array_insert_unique(con->response.headers, (data_unset *)ds);
 +              }
 +
 +      if (sess->state == PROXY_STATE_CONNECTED) {
 +              /* build the header */
-+              proxy_get_request_header(srv, con, sess);
++              proxy_get_request_header(srv, con, p, sess);
 +
 +              sess->state = PROXY_STATE_WRITE_REQUEST_HEADER;
 +      }
 +      return HANDLER_GO_ON;
 +}
 +
-+proxy_backend *proxy_get_backend(server *srv, connection *con, plugin_data *p, buffer *uri) {
++proxy_backend *proxy_get_backend(server *srv, connection *con, plugin_data *p) {
 +      size_t i;
 +
 +      for (i = 0; i < p->conf.backends->used; i++) {
 +      PATCH_OPTION(backends);
 +      PATCH_OPTION(backlog);
 +      PATCH_OPTION(protocol);
++      PATCH_OPTION(request_rewrites);
++      PATCH_OPTION(response_rewrites);
 +
 +      /* skip the first, the global context */
 +      for (i = 1; i < srv->config_context->used; i++) {
 +              for (j = 0; j < dc->value->used; j++) {
 +                      data_unset *du = dc->value->data[j];
 +
-+                      if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.backends"))) {
++                      if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy-core.backends"))) {
 +                              PATCH_OPTION(backends);
 +                              PATCH_OPTION(backlog);
-+                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.debug"))) {
++                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy-core.debug"))) {
 +                              PATCH_OPTION(debug);
-+                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.balancer"))) {
++                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy-core.balancer"))) {
 +                              PATCH_OPTION(balancer);
-+                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.protocol"))) {
++                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy-core.protocol"))) {
 +                              PATCH_OPTION(protocol);
++                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_PROXY_CORE_REWRITE_REQUEST))) {
++                              PATCH_OPTION(request_rewrites);
++                      } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_PROXY_CORE_REWRITE_RESPONSE))) {
++                              PATCH_OPTION(response_rewrites);
 +                      }
 +              }
 +      }
 +
 +      mod_proxy_core_patch_connection(srv, con, p);
 +
++      if (p->conf.backends->used == 0) return HANDLER_GO_ON;
++
 +      /* 
 +       * 0. build session
 +       * 1. get a proxy connection
 +      while (1) {
 +              if (sess->proxy_con == NULL) {
 +                      proxy_address *address = NULL;
-+                      if (NULL == (sess->proxy_backend = proxy_get_backend(srv, con, p, con->uri.path))) {
++                      if (NULL == (sess->proxy_backend = proxy_get_backend(srv, con, p))) {
 +                              /* no connection pool for this location */
 +                              SEGFAULT();
 +                      }
 +
 +#endif
 +
+--- ../lighttpd-1.4.11/src/mod_proxy_core_rewrites.c   1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/mod_proxy_core_rewrites.c      2006-07-18 17:34:32.000000000 +0300
+@@ -0,0 +1,64 @@
++#include <stdlib.h>
++#include <string.h>
++
++#include "mod_proxy_core_rewrites.h"
++#include "log.h"
++
++proxy_rewrite *proxy_rewrite_init(void) {
++      STRUCT_INIT(proxy_rewrite, rewrite);
++
++      rewrite->header = buffer_init();
++      rewrite->match = buffer_init();
++      rewrite->replace = buffer_init();
++
++      return rewrite;
++
++}
++void proxy_rewrite_free(proxy_rewrite *rewrite) {
++      if (!rewrite) return;
++
++      if (rewrite->regex) pcre_free(rewrite->regex);
++
++      buffer_free(rewrite->header);
++      buffer_free(rewrite->match);
++      buffer_free(rewrite->replace);
++
++      free(rewrite);
++}
++
++int proxy_rewrite_set_regex(proxy_rewrite *rewrite, buffer *regex) {
++      const char *errptr;
++      int erroff;
++
++      if (NULL == (rewrite->regex = pcre_compile(BUF_STR(regex),
++                0, &errptr, &erroff, NULL))) {
++              
++              TRACE("regex compilation for %s failed at %s", BUF_STR(regex), errptr);
++
++              return -1;
++      }
++
++      return 0;
++}
++
++
++proxy_rewrites *proxy_rewrites_init(void) {
++      STRUCT_INIT(proxy_rewrites, rewrites);
++
++      return rewrites;
++}
++
++void proxy_rewrites_add(proxy_rewrites *rewrites, proxy_rewrite *rewrite) {
++      ARRAY_STATIC_PREPARE_APPEND(rewrites);
++
++      rewrites->ptr[rewrites->used++] = rewrite;
++}
++
++void proxy_rewrites_free(proxy_rewrites *rewrites) {
++      if (!rewrites) return;
++
++      free(rewrites);
++}
++
++
++
+--- ../lighttpd-1.4.11/src/mod_proxy_core_rewrites.h   1970-01-01 03:00:00.000000000 +0300
++++ lighttpd-1.4.12/src/mod_proxy_core_rewrites.h      2006-07-18 17:34:32.000000000 +0300
+@@ -0,0 +1,28 @@
++#ifndef _MOD_PROXY_CORE_REWRITES_H_
++#define _MOD_PROXY_CORE_REWRITES_H_
++
++#include <pcre.h>
++#include "array-static.h"
++#include "buffer.h"
++
++typedef struct {
++      buffer *header;
++
++      pcre *regex; /* regex compiled from the <match> */
++
++      buffer *match;
++      buffer *replace;
++} proxy_rewrite;
++
++ARRAY_STATIC_DEF(proxy_rewrites, proxy_rewrite,);
++
++proxy_rewrite *proxy_rewrite_init(void);
++void proxy_rewrite_free(proxy_rewrite *rewrite);
++int proxy_rewrite_set_regex(proxy_rewrite *rewrite, buffer *regex);
++
++proxy_rewrites *proxy_rewrites_init(void);
++void proxy_rewrites_add(proxy_rewrites *rewrites, proxy_rewrite *rewrite);
++void proxy_rewrites_free(proxy_rewrites *rewrites);
++
++#endif
++
 --- ../lighttpd-1.4.11/src/mod_redirect.c      2006-02-08 15:38:06.000000000 +0200
 +++ lighttpd-1.4.12/src/mod_redirect.c 2006-07-16 00:26:04.000000000 +0300
 @@ -22,35 +22,35 @@
 +status.config-url           = "/server-config"
 +
 --- ../lighttpd-1.4.11/tests/docroot/www/dummydir/.svn/entries 2006-03-09 19:21:49.000000000 +0200
-+++ lighttpd-1.4.12/tests/docroot/www/dummydir/.svn/entries    2006-07-18 13:03:40.000000000 +0300
++++ lighttpd-1.4.12/tests/docroot/www/dummydir/.svn/entries    2006-07-18 17:34:32.000000000 +0300
 @@ -9,5 +9,6 @@
     last-author="jan"
     kind="dir"
     uuid="152afb58-edef-0310-8abb-c4023f1b3aa9"
 -   revision="1040"/>
 +   repos="svn://svn.lighttpd.net/lighttpd"
-+   revision="1199"/>
++   revision="1202"/>
  </wc-entries>
 --- ../lighttpd-1.4.11/tests/fastcgi-10.conf   2005-08-31 23:36:34.000000000 +0300
 +++ lighttpd-1.4.12/tests/fastcgi-10.conf      2006-07-16 00:26:04.000000000 +0300
This page took 0.264306 seconds and 4 git commands to generate.