예제 #1
0
파일: nope.c 프로젝트: janus/nope.c
void process(int fd,  fd_set *pMaster, struct sockaddr_in *clientaddr){
    printf("accept request, fd is %d, pid is %d\n", fd, getpid());

    int status = 200;

	char buf[1024];
	u_int numchars;
	char method[255];
	char url[1024];
	size_t i, j;
    int client=fd;

	numchars = getLine(client, buf, sizeof(buf));

	i = 0; j = 0;
	while (!ISspace(buf[j]) && (i < sizeof(method) - 1))
	{
		method[i] = buf[j];
		i++; j++;

	}
	method[i] = '\0';

	if (strcasecmp(method, "GET") && strcasecmp(method, "POST"))
	{
		unimplemented(client);
		return;
	}


	i = 0;
	while (ISspace(buf[j]) && (j < sizeof(buf)))
		j++;
	while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf)))
	{
		url[i] = buf[j];
		i++; j++;
	}
	url[i] = '\0';

	Request request;
	request.client=client;
	request.reqStr=url;
	request.method=method;

	/*server(client,url,method);*/

	server(request);

	close(client);

	http_request req;
	strncpy(req.filename, url, sizeof req.filename);
    log_access(status, clientaddr, &req);
}
예제 #2
0
//parse the first line into the array
//and store url method version into the header
int parse_resquest(char* buff,http_header* pheader)
{
    int i,j;
    i = j = 0;

    //read the method into the array
    while(!ISspace(buff[i]) &&  i<(sizeof(pheader->method) -1) )
    {
        pheader->method[j] = buff[i];
        i++,j++;
    }
    pheader->method[i] = '\0';

    //if the method not the "GET",return the unimplemented
    if( strcmp(pheader->method,"GET") != 0)
    {
        // debug_info
        printf("this method unimplemented !");
        //unimplemented method
        //unimplemented(cli_fd);
        //return -1 (method is unimplemented)
        return -1;
    }

    //skip all the space
    while(ISspace(buff[j]) && j<sizeof(buff))
        j++;

    //read the url into the array
    i = 0 ;
    while(!ISspace(buff[j]) && i<sizeof(pheader->url))
    {
        pheader->url[i] = buff[j];
        i++,j++;
    }
    pheader->url[i] = '\0';

    //read the version into the array
    while(ISspace(buff[j]) && j<sizeof(buff))
        j++;
    i = 0;
    while(!ISspace(buff[j]) && i<sizeof(pheader->version) )
    {
        pheader->version[i] = buff[j];
        i++,j++;
    }
    pheader->version[j] = '\0';

    return 0;
}
예제 #3
0
//Parse the request
int http_getrequest(char* buf, int size, char* src_buf)
{
 int i = 0;
 int j = 0;

 while (ISspace(src_buf[j]))
  j++; 

 while (!ISspace(src_buf[i+j]) && (i < size-1))
 {
  buf[i] = src_buf[i+j];
  i++;
 }
 buf[i] = '\0';
 
 return i+j;
}  
예제 #4
0
/**
 * Read event for EPOLLIN on the httpd protocol module.
 *
 * @param dcb	The descriptor control block
 * @return
 */
static int
httpd_read_event(DCB* dcb)
{
//SESSION		*session = dcb->session;
//ROUTER_OBJECT	*router = session->service->router;
//ROUTER		*router_instance = session->service->router_instance;
//void		*rsession = session->router_session;

int numchars = 1;
char buf[HTTPD_REQUESTLINE_MAXLEN-1] = "";
char *query_string = NULL;
char method[HTTPD_METHOD_MAXLEN-1] = "";
char url[HTTPD_SMALL_BUFFER] = "";
int cgi = 0;
size_t i, j;
int headers_read = 0;
HTTPD_session *client_data = NULL;

	client_data = dcb->data;

	/**
	 * get the request line
	 * METHOD URL HTTP_VER\r\n
	 */

	numchars = httpd_get_line(dcb->fd, buf, sizeof(buf));

	i = 0; j = 0;
	while (!ISspace(buf[j]) && (i < sizeof(method) - 1)) {
		method[i] = buf[j];
		i++; j++;
	}
	method[i] = '\0';

	strcpy(client_data->method, method);

	/* check allowed http methods */
	if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) {
		//httpd_unimplemented(dcb->fd);
		return 0;
	}

	if (strcasecmp(method, "POST") == 0)
		cgi = 1;

	i = 0;

	while (ISspace(buf[j]) && (j < sizeof(buf))) {
		j++;
	}

	while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) {
		url[i] = buf[j];
		i++; j++;
	}

	url[i] = '\0';

	/**
	 * Get the query string if availble
	 */

	if (strcasecmp(method, "GET") == 0) {
		query_string = url;
		while ((*query_string != '?') && (*query_string != '\0'))
			query_string++;
		if (*query_string == '?') {
			cgi = 1;
			*query_string = '\0';
			query_string++;
		}
	}

	/**
	 * Get the request headers
	 */

	while ((numchars > 0) && strcmp("\n", buf)) {
		char *value = NULL;
		char *end = NULL;
		numchars = httpd_get_line(dcb->fd, buf, sizeof(buf));
		if ( (value = strchr(buf, ':'))) {
			*value = '\0';
			value++;
			end = &value[strlen(value) -1];
			*end = '\0';

			if (strncasecmp(buf, "Hostname", 6) == 0) {
				strcpy(client_data->hostname, value);
			}
			if (strncasecmp(buf, "useragent", 9) == 0) {
				strcpy(client_data->useragent, value);
			}
		}
	}

	if (numchars) {
		headers_read = 1;
		memcpy(&client_data->headers_received, &headers_read, sizeof(int));
	}

	/**
	 * Now begins the server reply
	 */

	/* send all the basic headers and close with \r\n */
	httpd_send_headers(dcb, 1);

	/**
	 * ToDO: launch proper content handling based on the requested URI, later REST interface
	 *
	 */

	dcb_printf(dcb, "Welcome to HTTPD Gateway (c) %s\n\n", version_str);

	if (strcmp(url, "/show") == 0) {
		if (strlen(query_string)) {
			if (strcmp(query_string, "dcb") == 0)
				dprintAllDCBs(dcb);
			if (strcmp(query_string, "session") == 0)
				dprintAllSessions(dcb);
		}
	}

	/* force the client connecton close */
	dcb->func.close(dcb);	

	return 0;
}
예제 #5
0
void accept_request(int client)
{
 char buf[1024];
 int numchars;
 char method[255];
 char url[255];
 char path[512];
 size_t i, j;
 struct stat st;
 int cgi = 0;      /* becomes true if server decides this is a CGI
                    * program */
 char *query_string = NULL;

 numchars = get_line(client, buf, sizeof(buf));
 i = 0; j = 0;
 while (!ISspace(buf[j]) && (i < sizeof(method) - 1))
 {
  method[i] = buf[j];
  i++; j++;
 }
 method[i] = '\0';

 if (strcasecmp(method, "GET") && strcasecmp(method, "POST"))
 {
  unimplemented(client);
  return;
 }

 if (strcasecmp(method, "POST") == 0)
  cgi = 1;

 i = 0;
 while (ISspace(buf[j]) && (j < sizeof(buf)))
  j++;
 while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf)))
 {
  url[i] = buf[j];
  i++; j++;
 }
 url[i] = '\0';

 if (strcasecmp(method, "GET") == 0)
 {
  query_string = url;
  while ((*query_string != '?') && (*query_string != '\0'))
   query_string++;
  if (*query_string == '?')
  {
   cgi = 1;
   *query_string = '\0';
   query_string++;
  }
 }

 //sprintf(path, "htdocs%s", url);
 sprintf(path, ".%s", url);
 if (path[strlen(path) - 1] == '/')
  strcat(path, "index.html");
 if (stat(path, &st) == -1) {
  while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */
   numchars = get_line(client, buf, sizeof(buf));
  not_found(client);
 }
 else
 {
  if ((st.st_mode & S_IFMT) == S_IFDIR)
   strcat(path, "/index.html");
  if ((st.st_mode & S_IXUSR) ||
      (st.st_mode & S_IXGRP) ||
      (st.st_mode & S_IXOTH)    )
   cgi = 1;
  cgi = 0;//must not cgi
  if (!cgi)
   serve_file(client, path);
  else
   execute_cgi(client, path, method, query_string);
 }

 close(client);
}
예제 #6
0
void* accept_request(void* client1)  
//accept_request解析header里面的第一行获得request method(get/post)和请求路径,映射到htdoc文件夹下的路径,
//其中当对应的文件可执行的时候,就调用execute_cgi函数

{
 int client = (intptr_t)client1;
 char buf[1024];
 int numchars;
 char method[255];
 char url[255];
 char path[512];
 size_t i, j;
 struct stat st;
 int cgi = 0;      /* becomes true if server decides this is a CGI
                    * program */
 char *query_string = NULL;

 numchars = get_line(client, buf, sizeof(buf));
 i = 0; j = 0;
 while (!ISspace(buf[j]) && (i < sizeof(method) - 1))
 {
  method[i] = buf[j];
  i++; j++;
 }
 method[i] = '\0';

 if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) 
 { 
  unimplemented(client); // 仅仅支持GET和POST方法,否则抛出未支持的方法
  return NULL;
 }

 if (strcasecmp(method, "POST") == 0)
  cgi = 1;

 i = 0;
 while (ISspace(buf[j]) && (j < sizeof(buf)))
  j++;
 while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf)))
 {
  url[i] = buf[j];
  i++; j++;
 }
 url[i] = '\0';

 if (strcasecmp(method, "GET") == 0)
 {
  query_string = url;
  while ((*query_string != '?') && (*query_string != '\0'))
   query_string++;
  if (*query_string == '?')
  {
   cgi = 1;
   *query_string = '\0';
   query_string++;
  }
 }

 sprintf(path, "htdocs%s", url);
 if (path[strlen(path) - 1] == '/')
  strcat(path, "index.html");
 if (stat(path, &st) == -1) {
  while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */
   numchars = get_line(client, buf, sizeof(buf));
  not_found(client);
 }
 else
 {
  if ((st.st_mode & S_IFMT) == S_IFDIR)
   strcat(path, "/index.html");
  if ((st.st_mode & S_IXUSR) ||
      (st.st_mode & S_IXGRP) ||
      (st.st_mode & S_IXOTH)    )
   cgi = 1;
  if (!cgi)
   serve_file(client, path);
  else
   execute_cgi(client, path, method, query_string);
 }

 close(client);
 return NULL;
}
예제 #7
0
void accept_request(int client)
{
 char buf[1024];
 int numchars;
 char method[255];
 char url[255];
 char path[512];
 size_t i, j;
 struct stat st;
 int cgi = 0;      /* becomes true if server decides this is a CGI
                    * program */
 char *query_string = NULL;

 numchars = get_line(client, buf, sizeof(buf));//把client里的\r都换成\n
 i = 0; j = 0;
 //找出method是get还是post,只支持这两种方法
 while (!ISspace(buf[j]) && (i < sizeof(method) - 1))
 {
  method[i] = buf[j];
  i++; j++;
 }
 method[i] = '\0';

 //函数说明 strcasecmp()用来比较参数s1和s2字符串,比较时会自动忽略大小写的差异。
//返回值 若参数s1和s2字符串相等则返回0。s1大于s2则返回大于0 的值,s1 小于s2 则返回小于0的值。
 if (strcasecmp(method, "GET") && strcasecmp(method, "POST"))
 {
  unimplemented(client);//返回给浏览器表明收到的 HTTP 请求所用的 method 不被支持。
  return;
 }

 if (strcasecmp(method, "POST") == 0)
  cgi = 1;

 i = 0;
 while (ISspace(buf[j]) && (j < sizeof(buf)))
  j++;

//找出URL
 while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf)))
 {
  url[i] = buf[j];
  i++; j++;
 }
 url[i] = '\0';


 if (strcasecmp(method, "GET") == 0)
 {
  query_string = url;
  while ((*query_string != '?') && (*query_string != '\0'))
   query_string++;
  if (*query_string == '?')
  {
   cgi = 1;
   *query_string = '\0';
   query_string++;
  }
 }

 sprintf(path, "htdocs%s", url);
 if (path[strlen(path) - 1] == '/')
  strcat(path, "index.html");
 if (stat(path, &st) == -1) {
  while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */
   numchars = get_line(client, buf, sizeof(buf));
  not_found(client);
 }
 else
 {
  if ((st.st_mode & S_IFMT) == S_IFDIR)
   strcat(path, "/index.html");
  if ((st.st_mode & S_IXUSR) ||
      (st.st_mode & S_IXGRP) ||
      (st.st_mode & S_IXOTH)    )
   cgi = 1;
  if (!cgi)
   serve_file(client, path);
  else
   execute_cgi(client, path, method, query_string);
 }

 close(client);
}
예제 #8
0
void accept_request(int client)  
{  
    char buf[1024];  
    int numchars;  
    char method[255];  
    char url[255];  
    char path[512];  
    size_t i, j;  
    struct stat st;  
    int cgi = 0;      /* becomes true if server decides this is a CGI program */  
    char *query_string = NULL;  
  
    /*得到请求的第一行*/  
    numchars = get_line(client, buf, sizeof(buf));  
    i = 0; j = 0;  
    /*把客户端的请求方法存到 method 数组*/  
    while (!ISspace(buf[j]) && (i < sizeof(method) - 1))  
    {  
        method[i] = buf[j];  
        i++; j++;  
    }  
    method[i] = '\0';  
  
    /*如果既不是 GET 又不是 POST 则无法处理 */  
    if (strcasecmp(method, "GET") && strcasecmp(method, "POST"))  
    {  
        unimplemented(client);  
        return;  
    }  
  
    /* POST 的时候开启 cgi */  
    if (strcasecmp(method, "POST") == 0)  
        cgi = 1;  
  
    /*读取 url 地址*/  
    i = 0;  
    while (ISspace(buf[j]) && (j < sizeof(buf)))  
        j++;  
    while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf)))  
    {  
        /*存下 url */  
        url[i] = buf[j];  
        i++; j++;  
    }  
    url[i] = '\0';  
  
    /*处理 GET 方法*/  
    if (strcasecmp(method, "GET") == 0)  
    {  
        /* 待处理请求为 url */  
        query_string = url;  
        while ((*query_string != '?') && (*query_string != '\0'))  
            query_string++;  
        /* GET 方法特点,? 后面为参数*/  
        if (*query_string == '?')  
        {  
            /*开启 cgi */  
            cgi = 1;  
            *query_string = '\0';  
            query_string++;  
        }  
    }  
  
    /*格式化 url 到 path 数组,html 文件都在 htdocs 中*/  
    sprintf(path, "htdocs%s", url);  
    /*默认情况为 index.html */  
    if (path[strlen(path) - 1] == '/')  
        strcat(path, "index.html");  
    /*根据路径找到对应文件 */  
    if (stat(path, &st) == -1) {  
        /*把所有 headers 的信息都丢弃*/  
        while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */  
            numchars = get_line(client, buf, sizeof(buf));  
        /*回应客户端找不到*/  
        not_found(client);  
    }  
    else  
    {  
        /*如果是个目录,则默认使用该目录下 index.html 文件*/  
        if ((st.st_mode & S_IFMT) == S_IFDIR)  
            strcat(path, "/index.html");  
      if ((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH)    )  
          cgi = 1;  
      /*不是 cgi,直接把服务器文件返回,否则执行 cgi */  
      if (!cgi)  
          serve_file(client, path);  
      else  
          execute_cgi(client, path, method, query_string);  
    }  
  
    /*断开与客户端的连接(HTTP 特点:无连接)*/  
    close(client);  
}  
예제 #9
0
파일: httpd.c 프로젝트: codewyh/TinyHttpd
void accept_request(void *arg)
{
 int client = *((int*)arg);
 char buf[1024];
 int numchars;
 char method[255];
 char url[255];
 char path[512];
 size_t i, j;
 struct stat st;
 int cgi = 0;      /* becomes true if server decides this is a CGI
                    * program */
 char *query_string = NULL;

 //读http 请求的第一行数据(request line),把请求方法存进 method 中
 numchars = get_line(client, buf, sizeof(buf));
 i = 0; j = 0;
 while (!ISspace(buf[j]) && (i < sizeof(method) - 1))
 {
  method[i] = buf[j];
  i++; j++;
 }
 method[i] = '\0';

 //如果请求的方法不是 GET 或 POST 任意一个的话就直接发送 response 告诉客户端没实现该方法
 if (strcasecmp(method, "GET") && strcasecmp(method, "POST"))
 {
  unimplemented(client);
  return;
 }

 //如果是 POST 方法就将 cgi 标志变量置一(true)
 if (strcasecmp(method, "POST") == 0)
  cgi = 1;

 i = 0;
 //跳过所有的空白字符(空格)
 while (ISspace(buf[j]) && (j < sizeof(buf))) 
  j++;
 
 //然后把 URL 读出来放到 url 数组中
 while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf)))
 {
  url[i] = buf[j];
  i++; j++;
 }
 url[i] = '\0';

 //如果这个请求是一个 GET 方法的话
 if (strcasecmp(method, "GET") == 0)
 {
  //用一个指针指向 url
  query_string = url;
  
  //去遍历这个 url,跳过字符 ?前面的所有字符,如果遍历完毕也没找到字符 ?则退出循环
  while ((*query_string != '?') && (*query_string != '\0'))
   query_string++;
  
  //退出循环后检查当前的字符是 ?还是字符串(url)的结尾
  if (*query_string == '?')
  {
   //如果是 ? 的话,证明这个请求需要调用 cgi,将 cgi 标志变量置一(true)
   cgi = 1;
   //从字符 ? 处把字符串 url 给分隔会两份
   *query_string = '\0';
   //使指针指向字符 ?后面的那个字符
   query_string++;
  }
 }

 //将前面分隔两份的前面那份字符串,拼接在字符串htdocs的后面之后就输出存储到数组 path 中。相当于现在 path 中存储着一个字符串
 sprintf(path, "htdocs%s", url);
 
 //如果 path 数组中的这个字符串的最后一个字符是以字符 / 结尾的话,就拼接上一个"index.html"的字符串。首页的意思
 if (path[strlen(path) - 1] == '/')
  strcat(path, "index.html");
 
 //在系统上去查询该文件是否存在
 if (stat(path, &st) == -1) {
  //如果不存在,那把这次 http 的请求后续的内容(head 和 body)全部读完并忽略
  while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */
   numchars = get_line(client, buf, sizeof(buf));
  //然后返回一个找不到文件的 response 给客户端
  not_found(client);
 }
 else
 {
	 LOG_INFO("accept request  1");
  //文件存在,那去跟常量S_IFMT相与,相与之后的值可以用来判断该文件是什么类型的
  //S_IFMT参读《TLPI》P281,与下面的三个常量一样是包含在<sys/stat.h>
  if ((st.st_mode & S_IFMT) == S_IFDIR)  
   //如果这个文件是个目录,那就需要再在 path 后面拼接一个"/index.html"的字符串
   strcat(path, "/index.html");
   
   //S_IXUSR, S_IXGRP, S_IXOTH三者可以参读《TLPI》P295
  if ((st.st_mode & S_IXUSR) ||       
      (st.st_mode & S_IXGRP) ||
      (st.st_mode & S_IXOTH)    )
   //如果这个文件是一个可执行文件,不论是属于用户/组/其他这三者类型的,就将 cgi 标志变量置一
   cgi = 1;
   
  if (!cgi)
   //如果不需要 cgi 机制的话,
   serve_file(client, path);
  else
   //如果需要则调用
   execute_cgi(client, path, method, query_string);
 }

 LOG_INFO("accept request end");
 close(client);
}
예제 #10
0
파일: httpd.c 프로젝트: bigshuai/MaxScale
/**
 * Read event for EPOLLIN on the httpd protocol module.
 *
 * @param dcb   The descriptor control block
 * @return
 */
static int httpd_read_event(DCB* dcb)
{
    SESSION *session = dcb->session;
    ROUTER_OBJECT *router = session->service->router;
    ROUTER *router_instance = session->service->router_instance;
    void *rsession = session->router_session;

    int numchars = 1;
    char buf[HTTPD_REQUESTLINE_MAXLEN-1] = "";
    char *query_string = NULL;
    char method[HTTPD_METHOD_MAXLEN-1] = "";
    char url[HTTPD_SMALL_BUFFER] = "";
    size_t i, j;
    int headers_read = 0;
    HTTPD_session *client_data = NULL;
    GWBUF *uri;

    client_data = dcb->data;

    /**
     * get the request line
     * METHOD URL HTTP_VER\r\n
     */

    numchars = httpd_get_line(dcb->fd, buf, sizeof(buf));

    i = 0; j = 0;
    while (!ISspace(buf[j]) && (i < sizeof(method) - 1))
    {
        method[i] = buf[j];
        i++; j++;
    }
    method[i] = '\0';

    strcpy(client_data->method, method);

    /* check allowed http methods */
    if (strcasecmp(method, "GET") && strcasecmp(method, "POST"))
    {
        //httpd_unimplemented(dcb->fd);
        return 0;
    }

    i = 0;

    while ( (j < sizeof(buf)) && ISspace(buf[j]))
    {
        j++;
    }

    while ((j < sizeof(buf) - 1) && !ISspace(buf[j]) && (i < sizeof(url) - 1))
    {
        url[i] = buf[j];
        i++; j++;
    }

    url[i] = '\0';

    /**
     * Get the query string if availble
     */

    if (strcasecmp(method, "GET") == 0)
    {
        query_string = url;
        while ((*query_string != '?') && (*query_string != '\0'))
        {
            query_string++;
        }
        if (*query_string == '?')
        {
            *query_string = '\0';
            query_string++;
        }
    }

    /**
     * Get the request headers
     */

    while ((numchars > 0) && strcmp("\n", buf))
    {
        char *value = NULL;
        char *end = NULL;
        numchars = httpd_get_line(dcb->fd, buf, sizeof(buf));
        if ((value = strchr(buf, ':')))
        {
            *value = '\0';
            value++;
            end = &value[strlen(value) -1];
            *end = '\0';

            if (strncasecmp(buf, "Hostname", 6) == 0)
            {
                strcpy(client_data->hostname, value);
            }
            if (strncasecmp(buf, "useragent", 9) == 0)
            {
                strcpy(client_data->useragent, value);
            }
        }
    }

    if (numchars)
    {
        headers_read = 1;
        memcpy(&client_data->headers_received, &headers_read, sizeof(int));
    }

    /**
     * Now begins the server reply
     */

    /* send all the basic headers and close with \r\n */
    httpd_send_headers(dcb, 1);

#if 0
    /**
     * ToDO: launch proper content handling based on the requested URI, later REST interface
     *
     */
    if (strcmp(url, "/show") == 0)
    {
        if (query_string && strlen(query_string))
        {
            if (strcmp(query_string, "dcb") == 0)
            {
                dprintAllDCBs(dcb);
            }
            if (strcmp(query_string, "session") == 0)
            {
                dprintAllSessions(dcb);
            }
        }
    }
    if (strcmp(url, "/services") == 0)
    {
        RESULTSET *set, *seviceGetList();
        if ((set = serviceGetList()) != NULL)
        {
            resultset_stream_json(set, dcb);
            resultset_free(set);
        }
    }
#endif
    if ((uri = gwbuf_alloc(strlen(url) + 1)) != NULL)
    {
        strcpy((char *)GWBUF_DATA(uri), url);
        gwbuf_set_type(uri, GWBUF_TYPE_HTTP);
        SESSION_ROUTE_QUERY(session, uri);
    }

    /* force the client connecton close */
    dcb_close(dcb);

    return 0;
}
예제 #11
0
void* accept_request(void* arg)
{
	int client=(int)arg;
	char buf[1024];
	int numchars;
	char method[255];
	char url[255];
	char path[512];
	size_t i, j;
	struct stat st;
	int cgi = 0;/* becomes true if server decides this is a CGI
                    * program */
	char *query_string = NULL;

	numchars = get_line(client, buf, sizeof(buf));
	i = 0; j = 0;
	//解析method:GET OR POST?
	while (!ISspace(buf[j]) && (i < sizeof(method) - 1))
	{
		method[i] = buf[j];
		i++; j++;
	}
	method[i] = '\0';

	if (strcasecmp(method, "GET") && strcasecmp(method, "POST"))
	{
		unimplemented(client);
		return NULL;
	}
	//如果method为POST,则开启CGI;
	if (strcasecmp(method, "POST") == 0)
		cgi = 1;

	i = 0;
	while (ISspace(buf[j]) && (j < sizeof(buf)))
		j++;
	//获取method对应的url,例如:url=/color.cgi?color=red;
	while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf)))
	{
		url[i] = buf[j];
		i++; j++;
	}
	url[i] = '\0';

	//如果method为GET,判断url中是否有CGI; 
	if (strcasecmp(method, "GET") == 0)
	{
		query_string = url;
		while ((*query_string != '?') && (*query_string != '\0'))
			query_string++;
		if (*query_string == '?')
		{
			cgi = 1;
			*query_string = '\0';
			query_string++;
		}
	}

	sprintf(path, "htdocs%s", url);
	if (path[strlen(path) - 1] == '/')
		strcat(path, "index.html");
	if (stat(path, &st) == -1) {
		while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */
			numchars = get_line(client, buf, sizeof(buf));
		not_found(client);
	}
	else
	{
		if ((st.st_mode & S_IFMT) == S_IFDIR)
			strcat(path, "/index.html");
		//如果path指定的文件为可执行文件,则CGI置位;
		if ((st.st_mode & S_IXUSR) ||
			(st.st_mode & S_IXGRP) ||
				(st.st_mode & S_IXOTH)    )
			cgi = 1;
		if (!cgi)
			serve_file(client, path);
		else
			execute_cgi(client, path, method, query_string);
	}

	close(client);
	return NULL;
}
예제 #12
0
/* ********************************
 * @描述:处理客户端HTTP请求
 * @输入:[in] client:	客户端地址
 * @输出: 无
 * ********************************/
void accept_request(int client)
{
	char buf[1024];
	int numchars;
	char method[255];
	char url[255];
	char path[512];
	size_t i, j;	// unsigned int
	struct stat st; // 保存文件信息
	int cgi = 0;	// 当服务端认为它是一个CGI时变成1
	char *query_string = NULL;

	/* 得到请求的第一行 */
	numchars = get_line(client, buf, sizeof(buf));
	i = 0;
	j = 0;
	
	/* 把客户端的请求方法存到method数组,遇到空格则停止 */
	while(!ISspace(buf[j]) && (i < sizeof(method) - 1))
	{
		method[i] = buf[j];
		i++; j++;
	}
	method[i] = '\0';
	
	/* 既不是GET也不是POST的情况,忽略大小写进行比较 */
	if(strcasecmp(method, "GET") && strcasecmp(method, "POST"))
	{
		unimplemented(client);
		return;
	}
	
	/* POST的情况,开启CGI */
	if(strcasecmp(method, "POST") == 0)
		cgi = 1;
	
	/* 读取URL地址 */
	i = 0;
	while(ISspace(buf[j]) && (j < sizeof(buf)))// 过滤掉空格
		j++;
	while(!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf)))
	{
		url[i] = buf[j]; // 存下URL
		i++; j++;
	}
	url[i] = '\0';

	/* 处理GET方法 */
	if(strcasecmp(method, "GET") == 0)
	{
		query_string = url;
		/* 找到URL中的? */
		while((*query_string != '?') && (*query_string != '\0'))
			query_string++;
		/* GET方法特点,?后面为参数 */
		if(*query_string == '?')
		{
			cgi = 1;
			*query_string = '\0';
			query_string++;		//query_string指向'?'后面
		}
	}

	/* 格式化URL到path数组,html文件在htdocs目录中 */
	sprintf(path, "htdocs%s", url);
	/* 默认情况为index.html */
	if(path[strlen(path) - 1] == '/')// path中最后一个字符
		strcat(path, "index.html");

	/* 根据路径找到对应文件 */
	if(stat(path, &st) == -1) // 通过文件名path获取文件信息,并保存到st中,-1表示失败
	{
		/* 读取并丢弃header */
		while((numchars > 0) && strcmp("\n", buf))// strcmp 相等返回0
			numchars = get_line(client, buf, sizeof(buf));
		not_found(client);
	}
	else
	{
		/* 如果是目录,则默认使用该目录下的index.html 文件*/
		if((st.st_mode & S_IFMT) == S_IFDIR)
			strcat(path, "/index.html");
		if((st.st_mode & S_IXUSR) ||
		   (st.st_mode & S_IXGRP) ||
		   (st.st_mode & S_IXOTH)    )
			cgi = 1;

		if(!cgi) // cgi == 0
			serve_file(client, path);
		else	 // cgi == 1
			execute_cgi(client, path, method, query_string);
	}
	/* 断开与客户端的连接 */
	close(client);
}
예제 #13
0
파일: httpd.c 프로젝트: sfeakes/gpioctrl
void accept_request(int client)
{
  char buf[1024];
  int numchars;
  char method[255];
  char url[255];
  char path[512];
  size_t i, j;
  struct stat st;
  //int cgi = 0;      /* becomes true if server decides this is a CGI program */
  char *query_string = NULL;

  numchars = get_line(client, buf, sizeof(buf));
  i = 0; j = 0;
  while (!ISspace(buf[j]) && (i < sizeof(method) - 1))
  {
    method[i] = buf[j];
    i++; j++;
  }
  method[i] = '\0';

  if (strcasecmp(method, "GET") && strcasecmp(method, "POST"))
  {
    unimplemented(client);
    close(client);
    return;
  }
/*
  if (strcasecmp(method, "POST") == 0)
  cgi = 1;
*/
  i = 0;
  while (ISspace(buf[j]) && (j < sizeof(buf)))
    j++;
  while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf)))
  {
    url[i] = buf[j];
    i++; j++;
  }
  url[i] = '\0';

  if (strcasecmp(method, "GET") == 0)
  {
    query_string = url;
    while ((*query_string != '?') && (*query_string != '\0'))
    query_string++;
    if (*query_string == '?')
    {
//      cgi = 1;
      *query_string = '\0';
      query_string++;
    }
  }
/*
  serve_gpio_request(client, NULL);
  */
  
  logMessage (LOG_DEBUG,"HTTPD processing %s %s\n",url, query_string);
  
  if ( strcmp(url, "/gpio") == 0 || strcmp(url, "/gpio/") == 0) {
    serve_gpio_request(client, query_string);
  } 
  else if ( strcmp(url, "/led") == 0 || strcmp(url, "/led/") == 0) 
  {
    serve_led_request(client, query_string);
  }
  else if ( strcmp(url, "/mh") == 0 || strcmp(url, "/mh/") == 0) 
  {
    serve_meteohub_request(client, query_string);
  }
  else
  {
    if ( _gpioconfig_.docroot != 0 )
      sprintf(path, "%s/%s", _gpioconfig_.docroot, url);
    else
      sprintf(path, "htdocs%s", url);
      
    if (path[strlen(path) - 1] == '/')
      strcat(path, "index.html");
 
    if (stat(path, &st) == -1) {
      while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */
        numchars = get_line(client, buf, sizeof(buf));
      not_found(client);
    }
    else
    {
      if ((st.st_mode & S_IFMT) == S_IFDIR)
      {
        while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */
          numchars = get_line(client, buf, sizeof(buf));
        not_found(client);
      } else {
        serve_file(client, path);
      }
      /*
      put cgi in here in the future
      */
    }
  }

  close(client);
}
예제 #14
0
파일: httpd.c 프로젝트: houjian/Tinyhttpd
// 处理客户端请求,服务器核心控制逻辑
void accept_request(int client)
{
 char buf[1024];
 int numchars;
 char method[255];
 char url[255];
 char path[512];
 size_t i, j;
 struct stat st;
 int cgi = 0;      /* becomes true if server decides this is a CGI
                    * program */
 char *query_string = NULL;

 numchars = get_line(client, buf, sizeof(buf)); // 读取请求行
 i = 0; j = 0;
 while (!ISspace(buf[j]) && (i < sizeof(method) - 1))
 {
  method[i] = buf[j];
  i++; j++;
 } // 循环截取出请求方法
 method[i] = '\0';

 if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) // 只接收GET和POST请求
 {
  unimplemented(client); // 响应未实现页面
  return;
 }

 if (strcasecmp(method, "POST") == 0) // POST请求
  cgi = 1;

 i = 0;
 while (ISspace(buf[j]) && (j < sizeof(buf))) // 刚才截取method后j定位到后面的一个空格处,现在一直向后移动j直到指向非空白字符
  j++;
 while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf)))
 {
  url[i] = buf[j];
  i++; j++;
 } // 循环截取出请求的url资源
 url[i] = '\0';

 if (strcasecmp(method, "GET") == 0) // GET请求
 {
  query_string = url; // 查询字符串在url中的?号后面
  while ((*query_string != '?') && (*query_string != '\0')) // 一直移动到?号处
   query_string++;
  if (*query_string == '?')
  {
   cgi = 1;
   *query_string = '\0'; // ?号置为\0,url就切出来了
   query_string++; // 查询字符串从?后面一个字符开始
  }
 }

 sprintf(path, "htdocs%s", url); // htdocs/url/   htdocs/res.html
 if (path[strlen(path) - 1] == '/') // 最后一个字符是‘/’,默认访问该目录下的 index.html 页面
  strcat(path, "index.html");
 if (stat(path, &st) == -1) { // 获取文件详细信息失败
  while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */ // 读取剩下的请求头
   numchars = get_line(client, buf, sizeof(buf));
  not_found(client); // 404
 }
 else
 {
  if ((st.st_mode & S_IFMT) == S_IFDIR) // 是一个目录,默认访问该目录下的 index.html 页面
   strcat(path, "/index.html");
  if ((st.st_mode & S_IXUSR) ||
      (st.st_mode & S_IXGRP) ||
      (st.st_mode & S_IXOTH)    ) // 这个资源有执行权限 包括 所有者 同组 其他人
   cgi = 1;
  if (!cgi)
   serve_file(client, path); // 请求的是个页面,返回这页面
  else
   execute_cgi(client, path, method, query_string); // cgi程序,可以执行这个程序,处理过程交给cgi程序
 }

 close(client); // 关闭client socket
}