You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by wr...@apache.org on 2004/08/12 00:52:47 UTC

cvs commit: httpd-2.0/modules/proxy mod_proxy_balancer.dsp proxy_balancer.c config.m4 mod_proxy.dsp

wrowe       2004/08/11 15:52:47

  Modified:    modules/proxy config.m4 mod_proxy.dsp
  Added:       modules/proxy mod_proxy_balancer.dsp proxy_balancer.c
  Log:
  Add proxy_balancer to proxy module, including config and capturing
  -I ../generators for the mod_status.h
  
  Submitted by: mturk
  
  Revision  Changes    Path
  1.19      +6 -0      httpd-2.0/modules/proxy/config.m4
  
  Index: config.m4
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/proxy/config.m4,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- config.m4	11 Aug 2004 20:29:46 -0000	1.18
  +++ config.m4	11 Aug 2004 22:52:46 -0000	1.19
  @@ -17,6 +17,7 @@
   proxy_ftp_objs="proxy_ftp.lo"
   proxy_http_objs="proxy_http.lo"
   proxy_ajp_objs="proxy_ajp.lo ajp_header.lo ajp_link.lo ajp_msg.lo"
  +proxy_balancer_objs="proxy_balancer.lo"
   
   case "$host" in
     *os2*)
  @@ -25,12 +26,17 @@
       proxy_connect_objs="$proxy_connect_objs mod_proxy.la"
       proxy_ftp_objs="$proxy_ftp_objs mod_proxy.la"
       proxy_http_objs="$proxy_http_objs mod_proxy.la"
  +    proxy_balancer_objs="$proxy_balancer_objs mod_proxy.la"
       ;;
   esac
   
   APACHE_MODULE(proxy_connect, Apache proxy CONNECT module, $proxy_connect_objs, , $proxy_mods_enable)
   APACHE_MODULE(proxy_ftp, Apache proxy FTP module, $proxy_ftp_objs, , $proxy_mods_enable)
   APACHE_MODULE(proxy_http, Apache proxy HTTP module, $proxy_http_objs, , $proxy_mods_enable)
  +APACHE_MODULE(proxy_balancer, Apache proxy BALANCER module, $proxy_balancer_objs, , $proxy_mods_enable)
  +
  +APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current/../generators])
  +
   APACHE_MODULE(proxy_ajp, Apache proxy AJP module, $proxy_ajp_objs, , no)
   
   if test "$proxy_ajp_enable" != "no" -o "$enable_proxy_ajp" != "no"; then
  
  
  
  1.26      +2 -2      httpd-2.0/modules/proxy/mod_proxy.dsp
  
  Index: mod_proxy.dsp
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/proxy/mod_proxy.dsp,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- mod_proxy.dsp	1 Mar 2004 18:06:08 -0000	1.25
  +++ mod_proxy.dsp	11 Aug 2004 22:52:46 -0000	1.26
  @@ -43,7 +43,7 @@
   # PROP Ignore_Export_Lib 0
   # PROP Target_Dir ""
   # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
  -# ADD CPP /nologo /MD /W3 /Zi /O2 /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PROXY_DECLARE_EXPORT" /Fd"Release\mod_proxy_src" /FD /c
  +# ADD CPP /nologo /MD /W3 /Zi /O2 /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../generators" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PROXY_DECLARE_EXPORT" /Fd"Release\mod_proxy_src" /FD /c
   # ADD BASE MTL /nologo /D "NDEBUG" /win32
   # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
   # ADD BASE RSC /l 0x809 /d "NDEBUG"
  @@ -69,7 +69,7 @@
   # PROP Ignore_Export_Lib 0
   # PROP Target_Dir ""
   # ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
  -# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "PROXY_DECLARE_EXPORT" /Fd"Debug\mod_proxy_src" /FD /c
  +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../ssl" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../generators" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "PROXY_DECLARE_EXPORT" /Fd"Debug\mod_proxy_src" /FD /c
   # ADD BASE MTL /nologo /D "_DEBUG" /win32
   # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
   # ADD BASE RSC /l 0x809 /d "_DEBUG"
  
  
  
  1.1                  httpd-2.0/modules/proxy/mod_proxy_balancer.dsp
  
  Index: mod_proxy_balancer.dsp
  ===================================================================
  # Microsoft Developer Studio Project File - Name="mod_proxy_balancer" - Package Owner=<4>
  # Microsoft Developer Studio Generated Build File, Format Version 6.00
  # ** DO NOT EDIT **
  
  # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
  
  CFG=mod_proxy_balancer - Win32 Release
  !MESSAGE This is not a valid makefile. To build this project using NMAKE,
  !MESSAGE use the Export Makefile command and run
  !MESSAGE 
  !MESSAGE NMAKE /f "mod_proxy_balancer.mak".
  !MESSAGE 
  !MESSAGE You can specify a configuration when running NMAKE
  !MESSAGE by defining the macro CFG on the command line. For example:
  !MESSAGE 
  !MESSAGE NMAKE /f "mod_proxy_balancer.mak" CFG="mod_proxy_balancer - Win32 Release"
  !MESSAGE 
  !MESSAGE Possible choices for configuration are:
  !MESSAGE 
  !MESSAGE "mod_proxy_balancer - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
  !MESSAGE "mod_proxy_balancer - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
  !MESSAGE 
  
  # Begin Project
  # PROP AllowPerConfigDependencies 0
  # PROP Scc_ProjName ""
  # PROP Scc_LocalPath ""
  CPP=cl.exe
  MTL=midl.exe
  RSC=rc.exe
  
  !IF  "$(CFG)" == "mod_proxy_balancer - Win32 Release"
  
  # PROP BASE Use_MFC 0
  # PROP BASE Use_Debug_Libraries 0
  # PROP BASE Output_Dir "Release"
  # PROP BASE Intermediate_Dir "Release"
  # PROP BASE Target_Dir ""
  # PROP Use_MFC 0
  # PROP Use_Debug_Libraries 0
  # PROP Output_Dir "Release"
  # PROP Intermediate_Dir "Release"
  # PROP Ignore_Export_Lib 0
  # PROP Target_Dir ""
  # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
  # ADD CPP /nologo /MD /W3 /Zi /O2 /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_proxy_balancer_src" /FD /c
  # ADD BASE MTL /nologo /D "NDEBUG" /win32
  # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
  # ADD BASE RSC /l 0x809 /d "NDEBUG"
  # ADD RSC /l 0x809 /d "NDEBUG"
  BSC32=bscmake.exe
  # ADD BASE BSC32 /nologo
  # ADD BSC32 /nologo
  LINK32=link.exe
  # ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_proxy_balancer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_balancer.so
  # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_proxy_balancer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_balancer.so /opt:ref
  
  !ELSEIF  "$(CFG)" == "mod_proxy_balancer - Win32 Debug"
  
  # PROP BASE Use_MFC 0
  # PROP BASE Use_Debug_Libraries 1
  # PROP BASE Output_Dir "Debug"
  # PROP BASE Intermediate_Dir "Debug"
  # PROP BASE Target_Dir ""
  # PROP Use_MFC 0
  # PROP Use_Debug_Libraries 1
  # PROP Output_Dir "Debug"
  # PROP Intermediate_Dir "Debug"
  # PROP Ignore_Export_Lib 0
  # PROP Target_Dir ""
  # ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
  # ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_balancer_src" /FD /c
  # ADD BASE MTL /nologo /D "_DEBUG" /win32
  # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
  # ADD BASE RSC /l 0x809 /d "_DEBUG"
  # ADD RSC /l 0x809 /d "_DEBUG"
  BSC32=bscmake.exe
  # ADD BASE BSC32 /nologo
  # ADD BSC32 /nologo
  LINK32=link.exe
  # ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_proxy_balancer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_balancer.so
  # ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_proxy_balancer.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_balancer.so
  
  !ENDIF 
  
  # Begin Target
  
  # Name "mod_proxy_balancer - Win32 Release"
  # Name "mod_proxy_balancer - Win32 Debug"
  # Begin Group "Source Files"
  
  # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
  # Begin Source File
  
  SOURCE=.\proxy_balancer.c
  # End Source File
  # End Group
  # Begin Group "Header Files"
  
  # PROP Default_Filter ".h"
  # Begin Source File
  
  SOURCE=.\mod_proxy.h
  # End Source File
  # End Group
  # Begin Source File
  
  SOURCE=..\..\build\win32\win32ver.awk
  
  !IF  "$(CFG)" == "mod_proxy_balancer - Win32 Release"
  
  # PROP Ignore_Default_Tool 1
  # Begin Custom Build - Creating Version Resource
  InputPath=..\..\build\win32\win32ver.awk
  
  ".\mod_proxy_balancer.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
  	awk -f ../../build/win32/win32ver.awk mod_proxy_balancer.so "proxy_balancer_module for Apache" ../../include/ap_release.h > .\mod_proxy_balancer.rc
  
  # End Custom Build
  
  !ELSEIF  "$(CFG)" == "mod_proxy_balancer - Win32 Debug"
  
  # PROP Ignore_Default_Tool 1
  # Begin Custom Build - Creating Version Resource
  InputPath=..\..\build\win32\win32ver.awk
  
  ".\mod_proxy_balancer.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
  	awk -f ../../build/win32/win32ver.awk mod_proxy_balancer.so "proxy_balancer_module for Apache" ../../include/ap_release.h > .\mod_proxy_balancer.rc
  
  # End Custom Build
  
  !ENDIF 
  
  # End Source File
  # End Target
  # End Project
  
  
  
  1.1                  httpd-2.0/modules/proxy/proxy_balancer.c
  
  Index: proxy_balancer.c
  ===================================================================
  /* Copyright 1999-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  /* Load balancer module for Apache proxy */
  
  #define CORE_PRIVATE
  
  #include "mod_proxy.h"
  #include "ap_mpm.h"
  #include "apr_version.h"
  
  module AP_MODULE_DECLARE_DATA proxy_balancer_module;
  
  #if APR_HAS_THREADS1
  #define PROXY_BALANCER_LOCK(b)      apr_thread_mutex_lock((b)->mutex)
  #define PROXY_BALANCER_UNLOCK(b)    apr_thread_mutex_unlock((b)->mutex)
  #else
  #define PROXY_BALANCER_LOCK(b)      APR_SUCCESS
  #define PROXY_BALANCER_UNLOCK(b)    APR_SUCCESS
  #endif
  
  /* Retrieve the parameter with the given name                                */
  static char *get_path_param(apr_pool_t *pool, char *url,
                              const char *name)
  {
      char *path = NULL;
      
      for (path = strstr(url, name); path; path = strstr(path + 1, name)) {
          path += (strlen(name) + 1);
          if (*path == '=') {
              /*
               * Session path was found, get it's value
               */
              ++path;
              if (strlen(path)) {
                  char *q;
                  path = apr_pstrdup(pool, path);
                  if ((q = strchr(path, '?')))
                      *q = '\0';
                  return path;
              }
          }
      }
      return NULL;
  }
  
  static char *get_cookie_param(request_rec *r, const char *name)
  {
      const char *cookies;
      const char *start_cookie;
  
      if ((cookies = apr_table_get(r->headers_in, "Cookie"))) {
          for (start_cookie = strstr(cookies, name); start_cookie; 
               start_cookie = strstr(start_cookie + 1, name)) {
              if (start_cookie == cookies ||
                  start_cookie[-1] == ';' ||
                  start_cookie[-1] == ',' ||
                  isspace(start_cookie[-1])) {
                  
                  start_cookie += strlen(name);
                  while(*start_cookie && isspace(*start_cookie))
                      ++start_cookie;
                  if (*start_cookie == '=' && start_cookie[1]) {
                      /*
                       * Session cookie was found, get it's value
                       */
                      char *end_cookie, *cookie;
                      ++start_cookie;
                      cookie = apr_pstrdup(r->pool, start_cookie);
                      if ((end_cookie = strchr(cookie, ';')) != NULL)
                          *end_cookie = '\0';
                      if((end_cookie = strchr(cookie, ',')) != NULL)
                          *end_cookie = '\0';
                      return cookie;
                  }
              }
          }     
      }
      return NULL;
  }
  
  static proxy_runtime_worker *find_route_worker(proxy_balancer *balancer,
                                                 const char *route)
  {
      int i;
      proxy_runtime_worker *worker = (proxy_runtime_worker *)balancer->workers->elts;
      for (i = 0; i < balancer->workers->nelts; i++) {
          if (worker->route && strcmp(worker->route, route) == 0) {
              return worker;
          }
          worker++;
      }
      return NULL;
  }
  
  static proxy_runtime_worker *find_session_route(proxy_balancer *balancer,
                                                  request_rec *r,
                                                  char **route,
                                                  char **url)
  {
      if (!balancer->sticky)
          return NULL;
      /* Try to find the sticky route inside url */
      *route = get_path_param(r->pool, *url, balancer->sticky);
      if (!*route)
          *route = get_cookie_param(r, balancer->sticky);
      if (*route) {
          proxy_runtime_worker *worker =  find_route_worker(balancer, *route);
          /* TODO: make worker status codes */
          /* See if we have a redirection route */
          if (worker && worker->w->status < 2 && worker->redirect)
              worker = find_route_worker(balancer, worker->redirect);
          else
              worker = NULL;
          return worker;
      }
      else
          return NULL;
  }
  
  static int proxy_balancer_pre_request(proxy_worker **worker,
                                        proxy_balancer **balancer,
                                        request_rec *r,
                                        proxy_server_conf *conf, char **url)
  {
      int access_status = OK;
      proxy_runtime_worker *runtime;
      char *route;
      apr_status_t rv;
  
      /* Spet 1: check if the url is for us */
      if (!(*balancer = ap_proxy_get_balancer(r->pool, conf, *url)))
          return DECLINED;
      
      /* Step 2: find the session route */
      
      runtime = find_session_route(*balancer, r, &route, url);
      if (!runtime) {
          if (route && (*balancer)->sticky_force) {
              ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
                           "balancer: (%s). All workers in error state for route (%s)",
                           (*balancer)->name, route);
              return HTTP_SERVICE_UNAVAILABLE;
          }
      }
      /* Lock the LoadBalancer
       * XXX: perhaps we need the process lock here
       */
      if ((rv = PROXY_BALANCER_LOCK(*balancer)) != APR_SUCCESS) {
          ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
                       "proxy_balancer_pre_request: lock");
          return DECLINED;
      }
  
      PROXY_BALANCER_UNLOCK(*balancer);
  
      return access_status;
  } 
  
  static int proxy_balancer_post_request(proxy_worker *worker,
                                         proxy_balancer *balancer,
                                         request_rec *r,
                                         proxy_server_conf *conf)
  {
      int access_status;
      if (!balancer)
          access_status = DECLINED;
      else { 
          
  
          access_status = OK;
      }
  
      return access_status;
  } 
  
  static void ap_proxy_balancer_register_hook(apr_pool_t *p)
  {
      proxy_hook_pre_request(proxy_balancer_pre_request, NULL, NULL, APR_HOOK_FIRST);    
      proxy_hook_post_request(proxy_balancer_post_request, NULL, NULL, APR_HOOK_FIRST);    
  }
  
  module AP_MODULE_DECLARE_DATA proxy_balancer_module = {
      STANDARD20_MODULE_STUFF,
      NULL,		/* create per-directory config structure */
      NULL,		/* merge per-directory config structures */
      NULL,		/* create per-server config structure */
      NULL,		/* merge per-server config structures */
      NULL,		/* command apr_table_t */
      ap_proxy_balancer_register_hook	/* register hooks */
  };