예제 #1
0
void ResourceManager::loadFile(const std::string& fileName, std::iostream& out)
{
    out.clear(std::ios::goodbit);
    if(m_hasSearchPath) {
        std::string fullPath = resolvePath(fileName);
        PHYSFS_file* file = PHYSFS_openRead(fullPath.c_str());
        if(!file) {
            out.clear(std::ios::failbit);
            stdext::throw_exception(stdext::format("failed to load file '%s': %s", fullPath.c_str(), PHYSFS_getLastError()));
        } else {
            int fileSize = PHYSFS_fileLength(file);
            if(fileSize > 0) {
                std::vector<char> buffer(fileSize);
                PHYSFS_read(file, (void*)&buffer[0], 1, fileSize);
                out.write(&buffer[0], fileSize);
            } else
                out.clear(std::ios::eofbit);
            PHYSFS_close(file);
            out.seekg(0, std::ios::beg);
        }
    } else {
        std::ifstream fin(fileName);
        if(!fin) {
            out.clear(std::ios::failbit);
            stdext::throw_exception(stdext::format("failed to load file '%s': %s", fileName.c_str(), PHYSFS_getLastError()));
        } else {
            out << fin.rdbuf();
        }
    }
}
예제 #2
0
		void on_connected(socket& /*socket*/, std::iostream& stream)
		{
			for (std::size_t keep_alive_count = config_.maximum_keep_alive_requests; keep_alive_count != 0; --keep_alive_count)
			{
				stream.exceptions(std::ios_base::badbit);

				if (stream.peek() == EOF)
				{
					stream.clear();
					break;
				}

				stream.exceptions(std::ios_base::eofbit | std::ios_base::failbit | std::ios_base::badbit);

				http_server_context context(stream, config_);
				http_request& req = context.request();
				http_response& res = context.response();

				bool head = false;
				bool keep_alive = false;

				try
				{
					context.read_headers();

					switch (req.get_method())
					{
					case http_method::head:
						head = true;
						break;
					case http_method::get:
					case http_method::post:
						break;
					default:
						BOOST_THROW_EXCEPTION(http_exception(http_status_code::method_not_allowed));
					}

					if (req.is_connection_keep_alive())
					{
						res.set_keep_alive_requests(keep_alive_count);
						keep_alive = true;
					}

					context.validate_headers();

					if (config_.logger)
						config_.logger->http_server_request(req);

					try
					{
						switch (req.get_method())
						{
						case http_method::head:
						case http_method::get:
							derived().on_get(context, head);
							break;
						case http_method::post:
							derived().on_post(context);
							break;
						default:
							BOOST_THROW_EXCEPTION(http_exception(http_status_code::method_not_allowed));
						}
					}
					catch(http_exception&)
					{
						throw;
					}
					catch (interrupted_exception&)
					{
						throw;
					}
					catch (std::exception&)
					{
						BOOST_THROW_EXCEPTION(http_exception(http_status_code::internal_service_error));
					}
				}
				catch (http_exception& e)
				{
					if (config_.logger)
						config_.logger->exception();

					res.set_status_code(e.status_code());

					try
					{
						auto it = config_.error_document.find(e.status_code());
						if (it != config_.error_document.end())
							BOOST_THROW_EXCEPTION(http_exception(http_status_code::not_found));

						req.set_path(it->second);

						derived().on_get(context, head);
					}
					catch (http_exception&)
					{
						null_content().on_get(context, head);
					}
				}

				context.finish_write();

				if (!keep_alive)
					break;
			}
		}