ht的cgi处理过程

来源:互联网 发布:淘宝客成交订单在哪看 编辑:程序博客网 时间:2024/05/01 15:58

主要是cgi-bin/www文件处理客户请求的过程
用http://domain/SMAGIC/boa这样子。。这样的cgi对应的程序就是nju09/下的bbsboa.c

apache的httpd.conf里设置了cgi-bin的目录路径和调用的可执行处理文件www,然后客户端浏览器发送的请求(形如http://your_domain/SMGICXXXX)就直接通过apache调用www进行处理。

一、分析cgi环境变量SCRIPT_URL在BBSLIB.c里,url_parse()函数定义:

int
url_parse()
{
 char *url, *end, name[STRLEN], *p, *extraparam;
 url = getenv("SCRIPT_URL");
 if (NULL == url)
  return -1;
 strcpy(name, "/");
 if (!strncmp(url, "/" SMAGIC, sizeof (SMAGIC))) {
  snprintf(name, STRLEN, "%s", url + sizeof (SMAGIC));
  p = strchr(name, '/');
  if (NULL != p) {
   *p = 0;
   url = strchr(url + 1, '/');
  } else
   return -1;
 }
 extraparam = strchr(name, '_');
 if (extraparam) {
  *extraparam = 0;
  extraparam++;
 } else
  extraparam = "";
 extraparam_init(extraparam);
 loginok = user_init(&currentuser, &u_info, name);
 if (loginok)
  w_info = &(u_info->wwwinfo);
 else
  w_info = &guest;
 if (!strcmp(url, "/") || nologin) {
  strcpy(needcgi, "bbsindex");
  strcpy(rframe, "");
  strsncpy(name, getsenv("HTTP_HOST"), 70);
  p = strchr(name, '.');
  if (p != NULL && isaword(domainname, p + 1)) {
   *p = 0;
   strsncpy(rframe, name, 60);
  }
  if (rframe[0] && isaword(specname, rframe))
   rframe[0] = 0;
  return 0;
 }
 snprintf(needcgi, STRLEN, "%s", url + 1);
 if (NULL != (end = strchr(needcgi, '/')))
  *end = 0;
 return 0;
}

二、bbsmain.c里这样调用url_parse()

int
main(int argc, char *argv[])
{
 struct cgi_applet *a = NULL;
 struct rlimit rl;
 int i;
 seteuid(BBSUID);
 setuid(BBSUID);
 setgid(BBSGID);
 cgi_time(NULL);
 rl.rlim_cur = 100 * 1024 * 1024;
 rl.rlim_max = 100 * 1024 * 1024;
 setrlimit(RLIMIT_CORE, &rl);
 thispid = getpid();
 now_t = time(NULL);
 srand(now_t * 2 + thispid);
 if (initbbsinfo(&bbsinfo) < 0)
  exit(0);
 if (uhash_uptime() == 0) {
  exit(-1);
 }
 wwwcache = get_shm(WWWCACHE_SHMKEY, sizeof (struct WWWCACHE));
 if (NULL == wwwcache)
  exit(0);
 thisversion = file_time(argv[0]);
#ifndef USEBIG5
 if (thisversion > wwwcache->www_version)
  wwwcache->www_version = thisversion;
#endif
 html_header(0);
 if (geteuid() != BBSUID)
  http_fatal("uid error.");
 chdir(BBSHOME);
 shm_init(&bbsinfo);
 signal(SIGTERM, wantquit);
 if (access("NOLOGIN", F_OK))
  nologin = 0;
 get_att_server();
 get_tjpg_server();
 while (FCGI_Accept() >= 0) {
#ifdef USEBIG5
              start_outcache();
#endif
  cginame = NULL;
  incgiloop = 1;
  if (setjmp(cgi_start)) {
#ifdef USEBIG5
                      end_outcache();
#endif
   cgi_time(a);
   if (!incgiloop || wwwcache->www_version > thisversion
       || rt++ > 400000) {
    logtimeused();
    exit(2);
   }
   incgiloop = 0;
   continue;
  }
  html_header(0);
  hsprintf(NULL, NULL);
  now_t = time(NULL);
  via_proxy = 0;
  strsncpy(fromhost, getsenv("REMOTE_ADDR"), 32);
  inet_aton(fromhost, &from_addr);
  for (i = 0; wwwcache->validproxy[i] && i < MAX_PROXY_NUM; i++) {
   if (from_addr.s_addr == wwwcache->validproxy[i]) {
    via_proxy = 1;
    break;
   }
  }
  if (via_proxy
      || from_addr.s_addr == wwwcache->accel_addr.s_addr) {
   char *ptr, *p;
   int IPLEN = 255;
   ptr = getenv("HTTP_X_FORWARDED_FOR");
   if (!ptr)
    ptr = getsenv("REMOTE_ADDR");
   p = strrchr(ptr, ',');
   if (p != NULL) {
    while (!isdigit(*p) && *p)
     p++;
    if (*p)
     strncpy(fromhost, p, IPLEN);
    else
     strncpy(fromhost, ptr, IPLEN);
   } else
    strncpy(fromhost, ptr, IPLEN);
   fromhost[IPLEN] = 0;
   inet_aton(fromhost, &from_addr);
  }
  if (url_parse())
   http_fatal("%s 没有实现的功能!", getsenv("SCRIPT_URL"));
  http_parm_init();
  brc_expired();
  a = get_cgi_applet(needcgi);
  if (a != NULL) {
   cginame = a->name[0];
   //access(getsenv("QUERY_STRING"), F_OK);
   wwwcache->www_visit++;
   (*(a->main)) ();
#ifdef USEBIG5
                      end_outcache();
#endif
   cgi_time(a);
   if (!incgiloop || wwwcache->www_version > thisversion) {
    logtimeused();
    exit(4);
   }
   incgiloop = 0;
   continue;
  }
  http_fatal("%s 没有实现的功能!", getsenv("SCRIPT_URL"));
//              end_outcache();
  incgiloop = 0;
 }
 logtimeused();
 exit(5);
}

三、main()调用url_parse()以后,看url_parse()里面大略做的是:
先得到环境变量SCRIPT_URL的值,如上面的就是SCRIPT_URL="/SMAGIC/boa"
然后,截掉前面的部分,把剩下的boa赋给needcgi,然后返回main(),
然后main()以needcgi为参数调用get_cgi_applet(),根据needcgi从applets表中查到函数名

get_cgi_applet(char *needcgi)
{
 static ght_hash_table_t *p_table = NULL;
 struct cgi_applet *a;

 if (p_table == NULL) {
  int i;
  a = applets;
  p_table = ght_create(250);
  while (a->main != NULL) {
   a->count = 0;
   a->utime = 0;
   a->stime = 0;
   for (i = 0; a->name[i] != NULL; i++)
    ght_insert(p_table, (void *) a,
        strlen(a->name[i]),
        (void *) a->name[i]);
   a++;
  }
 }
 if (p_table == NULL)
  return NULL;
 return ght_get(p_table, strlen(needcgi), needcgi);
}
#else
struct cgi_applet *
get_cgi_applet(char *needcgi)
{
 struct cgi_applet *a;
 int i;
 a = applets;
 while (a->main != NULL) {
  for (i = 0; a->name[i] != NULL; i++)
   if (!strcmp(needcgi, a->name[i]))
    return a;
  a++;
 }
 return NULL;
}
#endif
既然url_parse()这样写的,http://domain/cgi-bin/www自然不行啦..


四、据needcgi从applets表中查到函数名,以下是可供/var/www/cgi-bin/下的可执行文件www调用的内部函数:

struct cgi_applet applets[] = {
//      {bbsusr_main, {"bbsusr", NULL}},
 {bbsucss_main,{"bbsucss",NULL}},
 {bbsdefcss_main,{"bbsdefcss",NULL}},
 {bbstop10_main, {"bbstop10", NULL}},
 {bbsdoc_main, {"bbsdoc", "doc", NULL}},
 {bbscon_main, {"bbscon", "con", NULL}},
 {bbsbrdadd_main, {"bbsbrdadd", "brdadd", NULL}},
 {bbsboa_main, {"bbsboa", "boa", NULL}},
 {bbsall_main, {"bbsall", NULL}},
 {bbsanc_main, {"bbsanc", "anc", NULL}},
 {bbs0an_main, {"bbs0an", "0an", NULL}},
 {bbslogout_main, {"bbslogout", NULL}},
 {bbsleft_main, {"bbsleft", NULL}},
 {bbslogin_main, {"bbslogin", NULL}},
 {bbsbadlogins_main, {"bbsbadlogins", NULL}},
 {bbsqry_main, {"bbsqry", "qry", NULL}},
 {bbsnot_main, {"bbsnot", "not", NULL}},
 {bbsfind_main, {"bbsfind", NULL}},
 {bbsfadd_main, {"bbsfadd", NULL}},
 {bbsfdel_main, {"bbsfdel", NULL}},
 {bbsfall_main, {"bbsfall", NULL}},
 {bbsfriend_main, {"bbsfriend", NULL}},
 {bbsfoot_main, {"bbsfoot", NULL}},
 {bbsform_main, {"bbsform", NULL}},
 {bbspwd_main, {"bbspwd", NULL}},
 {bbsplan_main, {"bbsplan", NULL}},
 {bbsinfo_main, {"bbsinfo", NULL}},
 {bbsmybrd_main, {"bbsmybrd", NULL}},
 {bbssig_main, {"bbssig", NULL}},
 {bbspst_main, {"bbspst", "pst", NULL}},
 {bbsgcon_main, {"bbsgcon", "gcon", NULL}},
 {bbsgdoc_main, {"bbsgdoc", "gdoc", NULL}},
 {bbsdel_main, {"bbsdel", "del", NULL}},
 {bbsdelmail_main, {"bbsdelmail", NULL}},
 {bbsmailcon_main, {"bbsmailcon", NULL}},
 {bbsmail_main, {"bbsmail", "mail", NULL}},
 {bbsdelmsg_main, {"bbsdelmsg", NULL}},
 {bbssnd_main, {"bbssnd", NULL}},
 {bbsnotepad_main, {"bbsnotepad", NULL}},
 {bbsmsg_main, {"bbsmsg", NULL}},
 {bbssendmsg_main, {"bbssendmsg", NULL}},
 {bbsreg_main, {"bbsreg", NULL}},
 {bbsscanreg_main, {"bbsscanreg", NULL}},
 {bbsmailmsg_main, {"bbsmailmsg", NULL}},
 {bbssndmail_main, {"bbssndmail", NULL}},
 {bbsnewmail_main, {"bbsnewmail", NULL}},
 {bbspstmail_main, {"bbspstmail", "pstmail", NULL}},
 {bbsgetmsg_main, {"bbsgetmsg", NULL}},
 //{bbschat_main, {"bbschat", NULL}},
 {bbscloak_main, {"bbscloak", NULL}},
 {bbsmdoc_main, {"bbsmdoc", "mdoc", NULL}},
 {bbsnick_main, {"bbsnick", NULL}},
 {bbstfind_main, {"bbstfind", "tfind", NULL}},
 {bbsadl_main, {"bbsadl", NULL}},
 {bbstcon_main, {"bbstcon", "tcon", NULL}},
 {bbstdoc_main, {"bbstdoc", "tdoc", NULL}},
 {bbsdoreg_main, {"bbsdoreg", NULL}},
 {bbsmywww_main, {"bbsmywww", NULL}},
 {bbsccc_main, {"bbsccc", "ccc", NULL}},
 //{bbsufind_main, {"bbsufind", NULL}},
 {bbsclear_main, {"bbsclear", "clear", NULL}},
 {bbsstat_main, {"bbsstat", NULL}},
 {bbsedit_main, {"bbsedit", "edit", NULL}},
 {bbsman_main, {"bbsman", "man", NULL}},
 {bbsparm_main, {"bbsparm", NULL}},
 {bbsfwd_main, {"bbsfwd", "fwd", NULL}},
 {bbsmnote_main, {"bbsmnote", NULL}},
 {bbsdenyall_main, {"bbsdenyall", NULL}},
 {bbsdenydel_main, {"bbsdenydel", NULL}},
 {bbsdenyadd_main, {"bbsdenyadd", NULL}},
 {bbstopb10_main, {"bbstopb10", NULL}},
 {bbsbfind_main, {"bbsbfind", "bfind", NULL}},
 {bbsx_main, {"bbsx", NULL}},
 {bbseva_main, {"bbseva", "eva", NULL}},
 {bbsvote_main, {"bbsvote", "vote", NULL}},
 {bbsshownav_main, {"bbsshownav", NULL}},
 {bbsbkndoc_main, {"bbsbkndoc", "bkndoc", NULL}},
 {bbsbknsel_main, {"bbsbknsel", "bknsel", NULL}},
 {bbsbkncon_main, {"bbsbkncon", "bkncon", NULL}},
 {bbshome_main, {"bbshome", "home", NULL}},
 {bbsindex_main, {"bbsindex", NULL}},
 {bbssechand_main, {"bbssechand", NULL}},
//      {bbsupload_main, {"bbsupload", NULL}},
 {bbslform_main, {"bbslform", NULL}},
 {bbslt_main, {"bbslt", NULL}},
 {bbsdt_main, {"bbsdt", NULL}},
 {regreq_main, {"regreq", NULL}},
 {bbsselstyle_main, {"bbsselstyle", NULL}},
 {bbscon1_main, {"bbscon1", "c1", NULL}},
 {bbsattach_main, {"attach", NULL}},
 {bbskick_main, {"kick", NULL}},
 {bbsshowfile_main, {"bbsshowfile", "showfile", NULL}},
 {bbsincon_main, {"boards", NULL}},
 {bbssetscript_main, {"setscript", NULL}},
 {bbscccmail_main, {"bbscccmail", NULL}},
 {bbsfwdmail_main, {"bbsfwdmail", NULL}},
 {bbsscanreg_findsurname_main, {"bbsscanreg_findsurname", NULL}},
 {bbsnt_main, {"bbsnt", NULL}},
 {bbstopcon_main, {"bbstopcon", NULL}},
 {bbsdrawscore_main, {"bbsdrawscore", NULL}},
 {bbsmyclass_main, {"bbsmyclass", NULL}},
 {bbssearchboard_main, {"bbssearchboard", NULL}},
 {bbsrss_main, {"bbsrss", NULL}},
 {bbslastip_main, {"bbslastip", NULL}},
 {bbsself_photo_vote_main, {"selfvote", NULL}},
 {bbsspam_main, {"bbsspam", NULL}},
 {bbsspamcon_main, {"bbsspamcon", NULL}},
 {bbssouke_main, {"bbssouke", NULL}},
 {bbsboardlistscript_main, {"bbsboardlistscript", "boardlistscript", NULL}},
 {bbsolympic_main, {"bbsolympic", "olympic", NULL}},
 {bbsicon_main, {"bbsicon", "icon", NULL}},
 {NULL}
}; 

原创粉丝点击