KLone APIs | Modules | Data Structures | File List | Data Fields | Globals

broker.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005, 2006, 2007 by KoanLogic s.r.l. <http://www.koanlogic.com>
00003  * All rights reserved.
00004  *
00005  * This file is part of KLone, and as such it is subject to the license stated
00006  * in the LICENSE file which you have received as part of this distribution.
00007  *
00008  * $Id: broker.c,v 1.21 2008/10/27 21:28:04 tat Exp $
00009  */
00010 
00011 #include <u/libu.h>
00012 #include <klone/supplier.h>
00013 #include <klone/broker.h>
00014 #include <klone/request.h>
00015 #include <klone/http.h>
00016 #include "klone_conf.h"
00017 
00018 enum { MAX_SUP_COUNT = 8 }; /* max number of suppliers */
00019 
00020 extern supplier_t sup_emb;
00021 #ifdef ENABLE_SUP_KILT
00022 extern supplier_t sup_kilt;
00023 #endif
00024 #ifdef ENABLE_SUP_CGI
00025 extern supplier_t sup_cgi;
00026 #endif
00027 #ifdef ENABLE_SUP_FS
00028 extern supplier_t sup_fs;
00029 #endif
00030 
00031 struct broker_s
00032 {
00033     supplier_t *sup_list[MAX_SUP_COUNT + 1];
00034 };
00035 
00036 int broker_is_valid_uri(broker_t *b, http_t *h, request_t *rq, const char *buf,
00037         size_t len)
00038 {
00039     int i;
00040     time_t mtime;
00041     void *handle;
00042 
00043     dbg_goto_if (b == NULL, notfound);
00044     dbg_goto_if (buf == NULL, notfound);
00045     
00046     for(i = 0; b->sup_list[i]; ++i)
00047     {
00048         if(b->sup_list[i]->is_valid_uri(h, rq, buf, len, &handle, &mtime))
00049         {
00050             request_set_sup_info(rq, b->sup_list[i], handle, mtime);
00051             return 1; /* found */
00052         }
00053     }
00054 notfound:
00055     return 0;
00056 }
00057 
00058 int broker_serve(broker_t *b, http_t *h, request_t *rq, response_t *rs)
00059 {
00060     const char *file_name;
00061     supplier_t *sup;
00062     void *handle;
00063     time_t mtime, ims;
00064     int i;
00065 
00066     dbg_err_if (b == NULL);
00067     dbg_err_if (rq == NULL);
00068     dbg_err_if (rs == NULL);
00069 
00070     /* get cached sup info */
00071     request_get_sup_info(rq, &sup, &handle, &mtime);
00072 
00073     if(sup == NULL)
00074     {
00075         file_name = request_get_resolved_filename(rq);
00076         for(i = 0; b->sup_list[i]; ++i)
00077         {
00078             if(b->sup_list[i]->is_valid_uri(h, rq, file_name, strlen(file_name),
00079                         &handle, &mtime) )
00080             {
00081                 sup = b->sup_list[i];
00082                 break;
00083             }
00084         }
00085         dbg_err_if(sup == NULL);
00086     }
00087     
00088     ims = request_get_if_modified_since(rq);
00089     if(ims && ims >= mtime)
00090     {
00091         response_set_status(rs, HTTP_STATUS_NOT_MODIFIED); 
00092         dbg_err_if(response_print_header(rs));
00093     } else {
00094         dbg_err_if(sup->serve(rq, rs));
00095 
00096         /* if the user explicitly set the status from a kl1 return 0 */
00097         if(response_get_status(rs) >= 400 && sup != &sup_emb 
00098                     #ifdef ENABLE_SUP_KILT
00099                     && sup!= &sup_kilt
00100                     #endif
00101                     )
00102             return response_get_status(rs);
00103     }
00104 
00105     return 0; /* page successfully served */
00106 err:
00107     response_set_status(rs, HTTP_STATUS_NOT_FOUND); 
00108     dbg("404, file not found: %s", request_get_filename(rq));
00109 
00110     return HTTP_STATUS_NOT_FOUND; /* page not found */
00111 }
00112 
00113 int broker_create(broker_t **pb)
00114 {
00115     broker_t *b = NULL;
00116     int i;
00117 
00118     dbg_err_if (pb == NULL);
00119 
00120     b = u_zalloc(sizeof(broker_t));
00121     dbg_err_if(b == NULL);
00122 
00123     i = 0;
00124     b->sup_list[i++] = &sup_emb;
00125 
00126 #ifdef ENABLE_SUP_KILT
00127     b->sup_list[i++] = &sup_kilt;
00128 #else
00129     warn("Kilt support disabled, use --enable_kilt to enable it");
00130 #endif
00131 
00132 #ifdef ENABLE_SUP_CGI
00133     b->sup_list[i++] = &sup_cgi;
00134 #else
00135 #ifndef OS_WIN
00136     warn("CGI support disabled, use --enable_cgi to enable it");
00137 #endif
00138 #endif
00139 
00140 #ifdef ENABLE_SUP_FS
00141     b->sup_list[i++] = &sup_fs;
00142 #else
00143     warn("File system support disabled, use --enable_fs to enable it");
00144 #endif
00145 
00146     b->sup_list[i++] = NULL;
00147 
00148     for(i = 0; b->sup_list[i]; ++i)
00149         dbg_err_if(b->sup_list[i]->init());
00150 
00151     *pb = b;
00152 
00153     return 0;
00154 err:
00155     if(b)
00156         broker_free(b);
00157     return ~0;
00158 }
00159 
00160 int broker_free(broker_t *b)
00161 {
00162     int i;
00163 
00164     if (b)
00165     {
00166         for(i = 0; b->sup_list[i]; ++i)
00167             b->sup_list[i]->term();
00168 
00169         U_FREE(b);
00170     }
00171 
00172     return 0;
00173 }
00174