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

📄 filemodule.cpp

📁 用c++编写http server的源码库,对socket等网络处理的代码可迅速转为己用.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		// determine the MIME type		response_file.mime_type = findMIMEType( response_file.file_path.leaf() );		// get the file_size and last_modified timestamp		response_file.update();		// just compare strings for simplicity (parsing this date format sucks!)		if (response_file.last_modified_string == if_modified_since) {			// no need to read the file; the modified times match!			response_type = RESPONSE_NOT_MODIFIED;		} else if (request->getMethod() == HTTPTypes::REQUEST_METHOD_HEAD) {			response_type = RESPONSE_HEAD_OK;		} else {			response_type = RESPONSE_OK;			// read the file (may throw exception)			response_file.read();			if (m_cache_setting != 0) {				// add new entry to the cache				PION_LOG_DEBUG(m_logger, "Adding cache entry for request ("							   << getResource() << "): " << relative_path);				boost::mutex::scoped_lock cache_lock(m_cache_mutex);				m_cache_map.insert( std::make_pair(relative_path, response_file) );			}		}	}			// prepare a response and set the Content-Type	HTTPResponsePtr response(HTTPResponse::create());	response->setContentType(response_file.mime_type);		// set Last-Modified header to enable client-side caching	response->addHeader(HTTPTypes::HEADER_LAST_MODIFIED, response_file.last_modified_string);	switch(response_type) {		case RESPONSE_UNDEFINED:			// this should never happen			throw UndefinedResponseException(request->getResource());			break;		case RESPONSE_NOT_MODIFIED:			// set "Not Modified" response			response->setResponseCode(HTTPTypes::RESPONSE_CODE_NOT_MODIFIED);			response->setResponseMessage(HTTPTypes::RESPONSE_MESSAGE_NOT_MODIFIED);			break;		case RESPONSE_OK:			// write the file's contents to the response stream			if (response_file.file_size != 0)				response->write(response_file.file_content.get(), response_file.file_size);			// fall through to RESPONSE_HEAD_OK		case RESPONSE_HEAD_OK:			// set "OK" response (not really necessary since this is the default)			response->setResponseCode(HTTPTypes::RESPONSE_CODE_OK);			response->setResponseMessage(HTTPTypes::RESPONSE_MESSAGE_OK);			break;	}		// send the response	response->send(tcp_conn);	return true;}void FileModule::start(void){	PION_LOG_DEBUG(m_logger, "Starting up resource (" << getResource() << ')');	// scan directory/file if scan setting != 0	if (m_scan_setting != 0) {		// force caching if scan == (2 | 3)		if (m_cache_setting == 0 && m_scan_setting > 1)			m_cache_setting = 1;				boost::mutex::scoped_lock cache_lock(m_cache_mutex);		// add entry for file if one is defined		if (! m_file.empty()) {			// use empty relative_path for file option			// use placeholder entry (do not pre-populate) if scan == 1			addCacheEntry("", m_file, m_scan_setting == 1);		}				// scan directory if one is defined		if (! m_directory.empty())			scanDirectory(m_directory);	}}void FileModule::stop(void){	PION_LOG_DEBUG(m_logger, "Shutting down resource (" << getResource() << ')');	// clear cached files (if started again, it will re-scan)	boost::mutex::scoped_lock cache_lock(m_cache_mutex);	m_cache_map.clear();}void FileModule::scanDirectory(const boost::filesystem::path& dir_path){	PION_LOG_DEBUG(m_logger, "Scanning directory (" << getResource() << "): "				   << dir_path.directory_string());		// iterate through items in the directory	boost::filesystem::directory_iterator end_itr;	for ( boost::filesystem::directory_iterator itr( dir_path );		  itr != end_itr; ++itr )	{		if ( boost::filesystem::is_directory(*itr) ) {			// item is a sub-directory						// recursively call scanDirectory()			scanDirectory(*itr);					} else {			// item is a regular file						// figure out relative path to the file			std::string file_path_string( itr->path().file_string() );			std::string relative_path( file_path_string.substr(m_directory.directory_string().size() + 1) );						// add item to cache (use placeholder if scan == 1)			addCacheEntry(relative_path, *itr, m_scan_setting == 1);		}	}}std::pair<FileModule::CacheMap::iterator, bool>FileModule::addCacheEntry(const std::string& relative_path,						  const boost::filesystem::path& file_path,						  const bool placeholder){	DiskFile cache_entry(file_path, NULL, 0, 0, findMIMEType(file_path.leaf()));	if (! placeholder) {		cache_entry.update();		try { cache_entry.read(); }		catch (std::exception& e) {			PION_LOG_ERROR(m_logger, "Unable to add file to cache: "						   << file_path.file_string());			return std::make_pair(m_cache_map.end(), false);		}	}		std::pair<CacheMap::iterator, bool> add_entry_result		= m_cache_map.insert( std::make_pair(relative_path, cache_entry) );		if (add_entry_result.second) {		PION_LOG_DEBUG(m_logger, "Added file to cache: "					   << file_path.file_string());	} else {		PION_LOG_ERROR(m_logger, "Unable to insert cache entry for file: "					   << file_path.file_string());	}		return add_entry_result;}std::string FileModule::findMIMEType(const std::string& file_name) {	// initialize m_mime_types if it hasn't been done already	boost::call_once(FileModule::createMIMETypes, m_mime_types_init_flag);		// determine the file's extension	std::string extension(file_name.substr(file_name.find_last_of('.') + 1));	std::transform(extension.begin(), extension.end(),				   extension.begin(), tolower);		// search for the matching mime type and return the result	MIMETypeMap::iterator i = m_mime_types_ptr->find(extension);	return (i == m_mime_types_ptr->end() ? DEFAULT_MIME_TYPE : i->second);}void FileModule::createMIMETypes(void) {	// create the map	static MIMETypeMap mime_types;		// populate mime types	mime_types["js"] = "text/javascript";	mime_types["txt"] = "text/plain";	mime_types["xml"] = "text/xml";	mime_types["css"] = "text/css";	mime_types["htm"] = "text/html";	mime_types["html"] = "text/html";	mime_types["xhtml"] = "text/html";	mime_types["gif"] = "image/gif";	mime_types["png"] = "image/png";	mime_types["jpg"] = "image/jpeg";	mime_types["jpeg"] = "image/jpeg";	// ...		// set the static pointer	m_mime_types_ptr = &mime_types;}// FileModule::DiskFile member functionsvoid FileModule::DiskFile::update(void){	// set file_size and last_modified	file_size = boost::filesystem::file_size( file_path );	last_modified = boost::filesystem::last_write_time( file_path );	last_modified_string = HTTPTypes::get_date_string( last_modified );}void FileModule::DiskFile::read(void){	// re-allocate storage buffer for the file's content	file_content.reset(new char[file_size]);		// open the file for reading	boost::filesystem::ifstream file_stream;	file_stream.open(file_path, std::ios::in | std::ios::binary);	// read the file into memory	if (!file_stream.is_open() || !file_stream.read(file_content.get(), file_size))		throw FileModule::FileReadException(file_path.file_string());}bool FileModule::DiskFile::checkUpdated(void){	// get current values	unsigned long cur_size = boost::filesystem::file_size( file_path );	time_t cur_modified = boost::filesystem::last_write_time( file_path );	// check if file has not been updated	if (cur_modified == last_modified && cur_size == file_size)		return false;	// file has been updated			// update file_size and last_modified timestamp	file_size = cur_size;	last_modified = cur_modified;	last_modified_string = HTTPTypes::get_date_string( last_modified );	// read new contents	read();		return true;}/// creates new FileModule objectsextern "C" FileModule *pion_create_FileModule(void){	return new FileModule();}/// destroys FileModule objectsextern "C" void pion_destroy_FileModule(FileModule *module_ptr){	delete module_ptr;}

⌨️ 快捷键说明

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