예제 #1
0
int http_response_write_header(server *srv, connection *con) {
	buffer *b;
	size_t i;
	int have_date = 0;
	int have_server = 0;

	b = chunkqueue_get_prepend_buffer(con->write_queue);

	if (con->request.http_version == HTTP_VERSION_1_1) {
		buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.1 "));
	} else {
		buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.0 "));
	}
	buffer_append_long(b, con->http_status);
	buffer_append_string_len(b, CONST_STR_LEN(" "));
	buffer_append_string(b, get_http_status_name(con->http_status));

	/* disable keep-alive if requested */
	if (con->request_count > con->conf.max_keep_alive_requests || 0 == con->conf.max_keep_alive_idle) {
		con->keep_alive = 0;
	} else {
		con->keep_alive_idle = con->conf.max_keep_alive_idle;
	}

	if (con->request.http_version != HTTP_VERSION_1_1 || con->keep_alive == 0) {
		if (con->keep_alive) {
			response_header_overwrite(srv, con, CONST_STR_LEN("Connection"), CONST_STR_LEN("keep-alive"));
		} else {
			response_header_overwrite(srv, con, CONST_STR_LEN("Connection"), CONST_STR_LEN("close"));
		}
	}

	if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
		response_header_overwrite(srv, con, CONST_STR_LEN("Transfer-Encoding"), CONST_STR_LEN("chunked"));
	}


	/* add all headers */
	for (i = 0; i < con->response.headers->used; i++) {
		data_string *ds;

		ds = (data_string *)con->response.headers->data[i];

		if (ds->value->used && ds->key->used &&
		    0 != strncasecmp(ds->key->ptr, CONST_STR_LEN("X-LIGHTTPD-")) &&
			0 != strncasecmp(ds->key->ptr, CONST_STR_LEN("X-Sendfile"))) {
			if (0 == strcasecmp(ds->key->ptr, "Date")) have_date = 1;
			if (0 == strcasecmp(ds->key->ptr, "Server")) have_server = 1;
			if (0 == strcasecmp(ds->key->ptr, "Content-Encoding") && 304 == con->http_status) continue;

			buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
			buffer_append_string_buffer(b, ds->key);
			buffer_append_string_len(b, CONST_STR_LEN(": "));
#if 0
			/** 
			 * the value might contain newlines, encode them with at least one white-space
			 */
			buffer_append_string_encoded(b, CONST_BUF_LEN(ds->value), ENCODING_HTTP_HEADER);
#else
			buffer_append_string_buffer(b, ds->value);
#endif
		}
	}

	if (!have_date) {
		/* HTTP/1.1 requires a Date: header */
		buffer_append_string_len(b, CONST_STR_LEN("\r\nDate: "));

		/* cache the generated timestamp */
		if (srv->cur_ts != srv->last_generated_date_ts) {
			buffer_prepare_copy(srv->ts_date_str, 255);

			strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1,
				 "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(srv->cur_ts)));

			srv->ts_date_str->used = strlen(srv->ts_date_str->ptr) + 1;

			srv->last_generated_date_ts = srv->cur_ts;
		}

		buffer_append_string_buffer(b, srv->ts_date_str);
	}

	if (!have_server) {
		if (buffer_is_empty(con->conf.server_tag)) {
			buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: " PACKAGE_DESC));
		} else if (con->conf.server_tag->used > 1) {
			buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: "));
			buffer_append_string_encoded(b, CONST_BUF_LEN(con->conf.server_tag), ENCODING_HTTP_HEADER);
		}
	}

	//- Jerry add 20110923
#if EMBEDDED_EANBLE	 
	char * ddns_host_n = nvram_get_ddns_host_name();	
	if(ddns_host_n){
		buffer_append_string_len(b, CONST_STR_LEN("\r\nDDNS: "));
		buffer_append_string(b, ddns_host_n);
	}else
#endif
	buffer_append_string_len(b, CONST_STR_LEN("\r\nDDNS: "));
	
	buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n"));


	con->bytes_header = b->used - 1;

	if (con->conf.log_response_header) {
		log_error_write(srv, __FILE__, __LINE__, "sSb", "Response-Header:", "\n", b);
	}

	return 0;
}
예제 #2
0
파일: response.c 프로젝트: kernelhcy/swiftd
int http_response_finish_header(server *srv, connection *con)
{
	if (NULL == srv || NULL == con || NULL == con -> write_queue)
	{
		return -1;
	}
	
	/*
	 * 这个header有安全问题。通产默认不添加。
	 */
	//http_response_insert_header(srv, con, CONST_STR_LEN("Server"), CONST_STR_LEN("Swiftd/0.1 written by hcy"));
	
	buffer *b = chunkqueue_get_prepend_buffer(con -> write_queue);
	if (NULL == b)
	{
		log_error_write(srv, __FILE__, __LINE__, "s", "chunkqueue_get_prepend_buffer failed.");
		return -1;
	}
	
	buffer_reset(b);
	
	/*
	 * Status-Line: 
	 *        HTTP-Version SP Status-Code SP Reason-Phrase CRLF
	 */
	buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.1"));
	buffer_append_string_len(b, CONST_STR_LEN(" "));	//SP
	buffer_append_long(b, con -> http_status);
	buffer_append_string_len(b, CONST_STR_LEN(" ")); 	//SP
	buffer_append_string(b, get_http_status_name(con -> http_status));
	buffer_append_string_len(b, CONST_STR_LEN(CRLF)); 	//CRLF = '\r\n' defined in base.h
	
	if(con -> keep_alive)
	{
		http_response_insert_header(srv, con, CONST_STR_LEN("Connection")
											, CONST_STR_LEN("keep-alive"));
	}
	else
	{
		http_response_insert_header(srv, con, CONST_STR_LEN("Connection")
											, CONST_STR_LEN("close"));
	}
	
	/*
	 * Headers:
	 *		Key:Value CRLF
	 */
	
	size_t i;
	data_string *ds;
	for (i = 0; i < con -> response.headers -> used; ++i)
	{
		ds = (data_string *)con -> response.headers -> data[i];
		if (NULL == ds)
		{
			continue;
		}
		buffer_append_string_buffer(b, ds -> key);
		buffer_append_string_len(b, CONST_STR_LEN(": "));
		buffer_append_string_buffer(b, ds -> value);
		buffer_append_string_len(b, CONST_STR_LEN(CRLF));
	}
	
	/*
	 * header 和 message body之间的CRLF。
	 */
	buffer_append_string_len(b, CONST_STR_LEN(CRLF));
	
	/*
	 * 最后一个'\0'不能发送出去!!
	 */
	-- b -> used;
	
	log_error_write(srv, __FILE__, __LINE__, "sb", "Response Headers:", b);
	array_reset(con -> response.headers);
	
	return 0;
}