2022年2月27日 星期日

lighttpd & CGI note


CGIC提供了簡單的API, 存取那一些CGIC已經幫你parse好的資料,比如: cgiRequestMethod, cgiRemoteAddr, cgiScriptName, 以及POST/GET資料等等, header的資料可以透過environ讀取
可以透過cgiFormEntries(char ***result)抓key, 再透過cgiFormString(char *name, char *result, int max)取得資料,
#include <stdio.h>
#include <cgic.h>
extern char **environ;

int cgiMain() {
  char **array, **arrayStep, val[64];
  fprintf(cgiOut, "cgiRequestMethod:%s\n", cgiRequestMethod);
  fprintf(cgiOut, "cgiRemoteAddr:%s\n", cgiRemoteAddr);
  fprintf(cgiOut, "cgiScriptName:%s\n", cgiScriptName);
  fprintf(cgiOut, "cgiContentType:%s\n", cgiContentType);
  fprintf(cgiOut, "used for GET, cgiQueryString:%s\n", cgiQueryString);

  if (cgiFormEntries(&array) == cgiFormSuccess) {
      for (arrayStep = array; *arrayStep; arrayStep++) {
          fprintf(cgiOut, "get post by cgiFormEntries():%s\n", *arrayStep);
          cgiFormString(*arrayStep, val, sizeof(val));
          fprintf(cgiOut, "val:%s\n", val);
      }
  }
  for (array = environ; *array; array++) {
      fprintf(cgiOut, "get from env:%s\n", *array);
  }

  return 0;
}


GET

[brook@:/var/www/html]$ curl -H "xhead: 123" --noproxy 127.0.0.1 http://127.0.0.1/cgic.cgi?xquery=123
cgiRequestMethod:GET
cgiRemoteAddr:127.0.0.1
cgiScriptName:/cgic.cgi
cgiContentType:
used for GET, cgiQueryString:xquery=123
get post by cgiFormEntries():xquery
val:123
get from env:CONTENT_LENGTH=0
get from env:QUERY_STRING=xquery=123
get from env:REQUEST_URI=/cgic.cgi?xquery=123
get from env:REDIRECT_STATUS=200
get from env:SCRIPT_NAME=/cgic.cgi
get from env:SCRIPT_FILENAME=/var/www/html/cgic.cgi
get from env:DOCUMENT_ROOT=/var/www/html
get from env:REQUEST_METHOD=GET
get from env:SERVER_PROTOCOL=HTTP/1.1
get from env:SERVER_SOFTWARE=lighttpd/1.4.64
get from env:GATEWAY_INTERFACE=CGI/1.1
get from env:REQUEST_SCHEME=http
get from env:SERVER_PORT=80
get from env:SERVER_ADDR=127.0.0.1
get from env:SERVER_NAME=127.0.0.1
get from env:REMOTE_ADDR=127.0.0.1
get from env:REMOTE_PORT=52894
get from env:HTTP_HOST=127.0.0.1
get from env:HTTP_USER_AGENT=curl/7.47.0
get from env:HTTP_ACCEPT=*/*
get from env:HTTP_XHEAD=123



POST

[brook@:/var/www/html]$ curl -H "xhead: 123" --noproxy 127.0.0.1 -X POST -d 'post1=p1&post2=p2' http://127.0.0.1/cgic.cgi?xquery=123
cgiRequestMethod:POST
cgiRemoteAddr:127.0.0.1
cgiScriptName:/cgic.cgi
cgiContentType:application/x-www-form-urlencoded
used for GET, cgiQueryString:xquery=123
get post by cgiFormEntries():post1
val:p1
get post by cgiFormEntries():post2
val:p2
get from env:CONTENT_LENGTH=17
get from env:QUERY_STRING=xquery=123
get from env:REQUEST_URI=/cgic.cgi?xquery=123
get from env:REDIRECT_STATUS=200
get from env:SCRIPT_NAME=/cgic.cgi
get from env:SCRIPT_FILENAME=/var/www/html/cgic.cgi
get from env:DOCUMENT_ROOT=/var/www/html
get from env:REQUEST_METHOD=POST
get from env:SERVER_PROTOCOL=HTTP/1.1
get from env:SERVER_SOFTWARE=lighttpd/1.4.64
get from env:GATEWAY_INTERFACE=CGI/1.1
get from env:REQUEST_SCHEME=http
get from env:SERVER_PORT=80
get from env:SERVER_ADDR=127.0.0.1
get from env:SERVER_NAME=127.0.0.1
get from env:REMOTE_ADDR=127.0.0.1
get from env:REMOTE_PORT=52904
get from env:HTTP_HOST=127.0.0.1
get from env:HTTP_USER_AGENT=curl/7.47.0
get from env:HTTP_ACCEPT=*/*
get from env:HTTP_XHEAD=123
get from env:HTTP_CONTENT_LENGTH=17
get from env:CONTENT_TYPE=application/x-www-form-urlencoded



header的部分會被轉成HTTP_VAR=val方式存在environment中, 相關的code如下,
http_cgi_encode_varname()
{
  if (is_http_header) {
    memcpy(p, "HTTP_", 5);
    j = 5; /* "HTTP_" */
  }
  /* uppercase alpha */
  ...
}

http_cgi_headers()
{
  ...
  for (n = 0; n < r->rqst_headers.used; n++) {
    http_cgi_encode_varname(tb, BUF_PTR_LEN(&ds->key), 1);
  }
  ...
}

cgi_create_env()
{
  /* create environment */
  http_cgi_headers(r, &opts, cgi_env_add, env);
  ...
  pid_t pid = (dfd >= 0) ? fdevent_fork_execve(args[0], args, envp,
    to_cgi_fds[0], from_cgi_fds[1], serrh_fd, dfd): -1;
  ...
}

mod_cgi_handle_subrequest()
{
  ...
  cgi_create_env();
  ...
}


熱門文章