⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpd_lib.c

📁 网页的客户端开发
💻 C
📖 第 1 页 / 共 3 页
字号:
					httpd_realloc_str(&hc->accepte, &hc->maxaccepte, strlen(cp));
				strcpy(hc->accepte, cp);
			}
	#ifdef _USE_TIME
			else if (strncasecmp(buf, "If-Modified-Since:", 18) == 0)
			{
				cp = &buf[18];
				hc->if_modified_since = tdate_parse(cp);
				// if (hc->if_modified_since == (time_t) -1)
					//syslog(LOG_DEBUG, "unparsable time: %.80s", cp);
			}
	#endif
			else if (strncasecmp(buf, "Cookie:", 7) == 0)
			{
				cp = &buf[7];
				cp += strspn(cp, " \t");
				hc->cookie = cp;
			}
			else if (strncasecmp(buf, "Range:", 6) == 0)
			{
				/* Only support %d- and %d-%d, not %d-%d,%d-%d or -%d. */
				if (strchr(buf, ',') == (char*) 0)
				{
					char* cp_dash;
					cp = strpbrk(buf, "=");
					if (cp != (char*) 0)
					{
						cp_dash = strchr(cp + 1, '-');
						if (cp_dash != (char*) 0 && cp_dash != cp + 1)
						{
							*cp_dash = '\0';
							hc->got_range = 1;
							hc->init_byte_loc = atol(cp + 1);
							if (isdigit((int) cp_dash[1]))
								hc->end_byte_loc = atol(cp_dash + 1);
						}
					}
				}
			}
			else if (strncasecmp(buf, "Range-If:", 9) == 0 ||
			  		 strncasecmp(buf, "If-Range:", 9) == 0)
			{
				cp = &buf[9];
				hc->range_if = tdate_parse(cp);
				// if (hc->range_if == (time_t) -1)
				//syslog(LOG_DEBUG, "unparsable time: %.80s", cp);
			}
			else if (strncasecmp(buf, "Content-Type:", 13) == 0)
			{
				cp = &buf[13];
				cp += strspn(cp, " \t");
				hc->contenttype = cp;
			}
			else if (strncasecmp(buf, "Content-Length:", 15) == 0)
			{
				cp = &buf[15];
				hc->contentlength = atol(cp);
			}
			else if (strncasecmp(buf, "Authorization:", 14) == 0)
			{
				cp = &buf[14];
				cp += strspn(cp, " \t");
				hc->authorization = cp;
			}
			else if (strncasecmp(buf, "Connection:", 11) == 0)
			{
				cp = &buf[11];
				cp += strspn(cp, " \t");
				if (strcasecmp(cp, "keep-alive") == 0)
				hc->keep_alive = 1;
			}

		}
	}

	if (hc->one_one)
	{
		/* Check that HTTP/1.1 requests specify a host, as required. */
		if (hc->reqhost[0] == '\0' && hc->hdrhost[0] == '\0')
		{
			httpd_send_err(hc, 400, httpd_err400title, httpd_err400form, "");
			return -1;
		}

		/* If the client wants to do keep-alives, it might also be doing
		** pipelining.  There's no way for us to tell.  Since we don't
		** implement keep-alives yet, if we close such a connection there
		** might be unread pipelined requests waiting.  So, we have to
		** do a lingering close.
		*/
		if (hc->keep_alive)
			hc->should_linger = 1;
	}

	/* Ok, the request has been parsed.  Now we resolve stuff that
	** may require the entire request.
	*/

	/* Copy original filename to expanded filename. */
	httpd_realloc_str (&hc->expnfilename, &hc->maxexpnfilename, strlen(hc->origfilename));
	strcpy(hc->expnfilename, hc->origfilename);

  #if 0
	if (hc->expnfilename[0] == '~')
	{
	}
  #endif 

	/* If the expanded filename is an absolute path, check that it's still
	** within the current directory or the alternate directory.
	*/
	return 0;
}


/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_start_request
*-----------------------------------------------------------------------
* DESCRIPTION: Start to handle HTTP client request 
* INPUT      : HTTPD_CONN_T* hc
* OUTPUT     : int   
*----------------------------------------------------------------------*/
int httpd_start_request(HTTPD_CONN_T* hc)
{
	int r;

	r = httpd_really_start_request(hc);

	return r;
}


/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_really_start_request
*-----------------------------------------------------------------------
* DESCRIPTION: Start to handle HTTP client request 
* INPUT      : HTTPD_CONN_T* hc
* OUTPUT     : int   
*----------------------------------------------------------------------*/
static int httpd_really_start_request(HTTPD_CONN_T* hc)
{

    // dprintf("hc->expnfilename=%s\n", hc->expnfilename);
	if (hc->method != METHOD_GET && hc->method != METHOD_HEAD &&
		hc->method != METHOD_POST)
	{
	    // dprintf("hc->method=%d\n", hc->method);
		httpd_send_err(hc, 500, err500title, err500form, hc->encodedurl);
		return -1;
	}

  #if 0 // old
	/* Stat the file. */
    if (http_stat(hc->expnfilename, &hc->sb, (hc->method == METHOD_POST) ? 1 : 0) < 0)
	{
		httpd_send_err(hc, 500, err500title, err500form, hc->encodedurl);
		return -1;
	}
  #endif
    {
		// (+) Car, 5-28-2002
		//	changed for cgi GET
		int	i;
		if ((hc->method == METHOD_GET && strcmp(hc->expnfilename, "config.bin")==0) )
		    i=0;
		else if (hc->method == METHOD_POST || (hc->method == METHOD_GET && *hc->query != 0))
			i = http_stat (hc->expnfilename, &hc->sb, 1);
		else
			i = http_stat (hc->expnfilename, &hc->sb, 0);
		if (i < 0)
		{
			httpd_send_err(hc, 500, err500title, err500form, hc->encodedurl);
			return -1;
		}
		// (-) Carl, 5-28-2002
    }  

// (+) Carl, 4-18-2002
	if (auth_check (hc, hc->expnfilename) == -1)
		return -1;
// (-) Carl, 4-18-2002

	// (+) Carl, 5-28-2002
	//	deal with POST/GET CGI method now
	if (hc->method == METHOD_POST || (hc->method == METHOD_GET && *hc->query != 0))
		return PostHandler (hc);
	// (-) Carl, 5-28-2002
	/* Fill in end_byte_loc if necessary. */
	if (hc->got_range && (hc->end_byte_loc == -1 || hc->end_byte_loc >= hc->sb.st_size))
		hc->end_byte_loc = hc->sb.st_size - 1;

	figure_mime(hc);

	if (hc->method == METHOD_HEAD)
	{
		hc->bytes = 0;
		httpd_send_mime (hc, 200, ok200title, hc->encodings, "", hc->type, hc->sb.st_size, hc->sb.st_mtime);
	}
	else
		if (hc->if_modified_since != (time_t) -1 && hc->if_modified_since == hc->sb.st_mtime)
		{
			hc->method = METHOD_HEAD;
			hc->bytes = 0;
			httpd_send_mime(hc, 304, err304title, hc->encodings, "", hc->type, hc->sb.st_size,
					  hc->sb.st_mtime);
		}
		else if (strcmp(hc->expnfilename, "config.bin")==0)
		{
		    UI8_T *cfg_file=(UI8_T *)image_create_cfg_file();  
			hc->bytes=IMG_WORK_CFG_FILE_SIZE+IMG_HDR_BLK_SIZE;
		    if ((hc->file_address=(char *)httpd_malloc(hc->bytes))==0)
			{
				httpd_send_err (hc, 500, err500title, err500form, hc->encodedurl);
				return -1;
			}
			memcpy(hc->file_address,cfg_file,hc->bytes);
			httpd_send_mime (hc, 200, ok200title, hc->encodings, "", hc->type, hc->bytes,
					   0);
		}
		else
		{
			hc->file_address = httpd_mmc_map (hc->expnfilename, &(hc->sb));
			if (hc->file_address == NULL)
			{
				httpd_send_err (hc, 500, err500title, err500form, hc->encodedurl);
				return -1;
			}
			hc->bytes = hc->sb.st_size;
			httpd_send_mime (hc, 200, ok200title, hc->encodings, "", hc->type, hc->sb.st_size,
					   hc->sb.st_mtime);
		}

	return 0;
}


/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_method_str
*-----------------------------------------------------------------------
* DESCRIPTION: Get HTTP client request method
* INPUT      : HTTPD_CONN_T* hc
* OUTPUT     : int   
*----------------------------------------------------------------------*/
static char* httpd_method_str(int method)
{
	switch (method)
	{
		case METHOD_GET:
			return "GET";

		case METHOD_HEAD:
			return "HEAD";

		case METHOD_POST:
			return "POST";

		default:
			return (char*) 0;
	}
}

/*----------------------------------------------------------------------
* ROUTINE NAME - httpd_bufgets
*-----------------------------------------------------------------------
* DESCRIPTION: 
* INPUT      : HTTPD_CONN_T* hc
* OUTPUT     : int   
*----------------------------------------------------------------------*/
static char* httpd_bufgets(HTTPD_CONN_T* hc)
{
	int i;
	char c;

	for (i = hc->checked_idx; hc->checked_idx < hc->read_idx; ++hc->checked_idx)
	{
		c = hc->read_buf[hc->checked_idx];
		if (c == '\n' || c == '\r')
		{
			hc->read_buf[hc->checked_idx] = '\0';
			++hc->checked_idx;
			if (c == '\r' && hc->checked_idx < hc->read_idx &&
		 		hc->read_buf[hc->checked_idx] == '\n')
			{
				hc->read_buf[hc->checked_idx] = '\0';
				++hc->checked_idx;
			}
			return &(hc->read_buf[i]);
		}
	}
	return (char*) 0;
}

/* Append a string to the buffer waiting to be sent as response. */
void httpd_add_response(HTTPD_CONN_T* hc, char* str)
{
	int len;

	len = strlen(str);
	httpd_realloc_str(&hc->response, &hc->maxresponse, hc->responselen + len);
	memcpy(&(hc->response[hc->responselen]), str, len);
	hc->responselen += len;
}

/* Send the buffered response. */
void httpd_write_response(HTTPD_CONN_T* hc)
{
	int flags;

	/* And send it, if necessary. */
	if (hc->responselen > 0)
	{
		 write(hc->conn_fd, hc->response, hc->responselen);
		hc->responselen = 0;
	}
}

static void httpd_send_mime(HTTPD_CONN_T* hc, int status, char* title, char* encodings, char* extraheads, char* type, int length, time_t mod)
{
  #ifdef _USE_TIME  
	time_t now;
	const char* rfc1123fmt = "%a, %d %b %Y %H:%M:%S GMT";
	char nowbuf[100];
	char modbuf[100];
  #endif	
	char buf[1000];
	int partial_content;

	hc->status = status;
	hc->bytes = length;
	if (hc->mime_flag)
	{
		if (status == 200 && hc->got_range && (hc->end_byte_loc >= hc->init_byte_loc) &&
			((hc->end_byte_loc != length - 1) || (hc->init_byte_loc != 0)) &&
		 	(hc->range_if == (time_t) -1 || hc->range_if == hc->sb.st_mtime))
		{
			partial_content = 1;
			hc->status = status = 206;
			title = ok206title;
		}
		else
			partial_content = 0;

     #ifdef _USE_TIME
		now = time((time_t*) 0);
		if (mod == (time_t) 0)
			mod = now;
		strftime(nowbuf, sizeof(nowbuf), rfc1123fmt, gmtime(&now));
		strftime(modbuf, sizeof(modbuf), rfc1123fmt, gmtime(&mod));
		snprintf(buf, sizeof(buf),
		"%.20s %d %s\r\nServer: %s\r\nContent-type: %s\r\nDate: %s\r\nLast-modified: %s\r\nAccept-Ranges: bytes\r\nConnection: close\r\n",
		hc->protocol, status, title, SERVER_SOFTWARE, type, nowbuf,
		modbuf);
	 #else
		snprintf(buf, sizeof(buf),
		//"%.20s %d %s\r\nServer: %s\r\nConnection: close\r\nContent-type: %s\r\n",
		"%.20s %d %s\r\nServer: %s\r\nContent-type: %s\r\n",
		hc->protocol, status, title, SERVER_SOFTWARE, type);
		
		if (memcmp(hc->expnfilename, "images/", 7)==0)
			strcat(buf, "Last-modified: Mon 2 Sep 2002 10:10:10\r\nExpires: Fri 6 Sep 2012 10:10:10\r\n");
	 	//dprintf("-->%s\r\n",hc->expnfilename);
	 #endif	
		httpd_add_response(hc, buf);
	 #if 0 // gary 9/5/2002
		if (encodings[0] != '\0')
		{
			snprintf(buf, sizeof(buf),
					"Content-encoding: %s\r\n", encodings);
			httpd_add_response(hc, buf);
		}
	 #endif
		if (partial_content)
		{
			snprintf(buf, sizeof(buf),
						   "Content-range: bytes %ld-%ld/%d\r\nContent-length: %ld\r\n",
						   (long) hc->init_byte_loc, (long) hc->end_byte_loc, length,
						   (long) (hc->end_byte_loc - hc->init_byte_loc + 1));
			httpd_add_response(hc, buf);
		}
		else
			if (length >= 0)
			{
				snprintf(buf, sizeof(buf),
								"Content-length: %d\r\n", length);
				httpd_add_response(hc, buf);
			}
		if (extraheads[0] != '\0')
			httpd_add_response(hc, extraheads);
		httpd_add_response(hc, "\r\n");
	}
}

void httpd_send_response (HTTPD_CONN_T* hc, int status, char* title, char* extrahead, char* form, char* arg)
{
	char buf[1000];

	httpd_send_mime (hc, status, title, "", extrahead, "text/html", -1, 0);
	snprintf(buf, sizeof(buf),
		"<HTML><HEAD><TITLE>%d %s</TITLE></HEAD>\n<BODY BGCOLOR=\"#cc9999\"><H2>%d %s</H2>\n",
	status, title, status, title);
	httpd_add_response(hc, buf);
	snprintf(buf, sizeof(buf),form, arg);
	httpd_add_response(hc, buf);
	snprintf(buf, sizeof(buf),"<HR>\n%</HTML>\n",SERVER_SOFTWARE);
	httpd_add_response(hc, buf);
}

void httpd_send_err(HTTPD_CONN_T* hc, int status, char* title, char* form, char* arg)
{
	httpd_send_response (hc, status, title, "", form, arg);
}


static LPVOID httpd_mmc_map (LPSTR filename, HTTP_STAT_T* sbP)
{
	HTTP_STAT_T sb;
	HTTP_FILE	*fd;
	INT 		len=0;
	LPSTR       addr;      

	/* Stat the file if necessary. */
	if (sbP != (HTTP_STAT_T *) 0)
		sb = *sbP;
	else
	{
		// find URI page file and get the associated state
		if (http_stat (filename, &sb, 0) != 0)
		{
			// syslog(LOG_ERR, "stat - %m");
			return (void*) 0;
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -