Esempio n. 1
0
int SaoriClient::request(
	const vector<string>& i_argument,
	bool i_is_secure,
	string& o_result,
	vector<string>& o_value)
{
	//---------------------
	// リクエスト作成

	strpairvec data;

	int idx=0;
	for ( vector<string>::const_iterator i=i_argument.begin() ; i!=i_argument.end() ; ++i,++idx )
	{
		data.push_back( strpair(string("Argument")+itos(idx), *i) );
	}
	data.push_back( strpair("SecurityLevel", (i_is_secure ? "Local" : "External") ) );

	//---------------------
	// リクエスト実行

	strpairvec r_data;
	int return_code = this->SakuraDLLClient::request("EXECUTE", data, r_data);

	//---------------------
	// 返答を解析

	string result;

	for ( strpairvec::const_iterator i = r_data.begin() ; i != r_data.end() ; ++i )
	{
		const string& key = i->first;
		const string& value = i->second;

		if ( compare_head(key, "Value") && isdigit(key[strlen("Value")]) )
		{
			const int	pos = atoi(key.c_str() + strlen("Value"));
			if ( pos<0 || pos>65536 )
			{
				continue;
			}

			if ( o_value.size() <= pos )
			{
				o_value.resize(pos+1);
			}
			o_value[pos] = value;
		}
		else if ( key=="Result" )
		{
			o_result = value;
		}
	}

	return return_code;
}
Esempio n. 2
0
// リクエストを送り、レスポンスを受け取る。戻り値はリターンコード。
int SakuraClient::request(
	const string& i_protocol,
	const string& i_protocol_version,
	const string& i_command,
	const strpairvec& i_data,
	
	string& o_protocol,
	string& o_protocol_version,
	strpairvec& o_data)
{
	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	// リクエスト文字列を作成

	string	request = i_command + " " + i_protocol + "/" + i_protocol_version + CRLF;
	for ( strpairvec::const_iterator it = i_data.begin() ; it != i_data.end() ; ++it )
	{
		request += it->first + ": " + it->second + CRLF;
	}
	request += CRLF;


	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	// リクエスト実行

	string response = this->request(request);


	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	// お返事を解析

	// 一行目を切り出し
	o_protocol = cut_token(response, "/");
	o_protocol_version = cut_token(response, " ");
	int return_code = atoi( cut_token(response, " ").c_str() );
	string return_string = cut_token(response, CRLF);

	// 以降のデータ行を切り出し
	while ( response.size() > 0 )
	{
		string value = cut_token(response, CRLF);
		string key = cut_token(value, ": ");
		o_data.push_back( strpair(key, value) );
	}
	
	return return_code;
}
int	Satori::request(
	const string& i_protocol,
	const string& i_protocol_version,
	const string& i_command,
	const strpairvec& i_data,
	
	string& o_protocol,
	string& o_protocol_version,
	strpairvec& o_data)
{
	SenderEnableBuffering seb(GetSender());

	//-------------------------------------------------
	// リクエスト単位のクラスメンバを初期化

	mRequestMap.clear();
	mRequestID = "";
	mReferences.clear();
	mReferences.reserve(8); // 最小値

	// 引数をクラスメンバに設定
	mRequestCommand = i_command;
	mRequestType = i_protocol;
	mRequestVersion = i_protocol_version;
	mStatusLine = i_command + " " + i_protocol + "/" + i_protocol_version;

	// 返すプロトコルのデフォルト値
	o_protocol = "SHIORI";
	o_protocol_version = "3.0";

	// 喋るごとに初期化する変数
	return_empty = false;

	surface_restore_at_talk_onetime = SR_INVALID;
	auto_anchor_enable_onetime = auto_anchor_enable;

	is_quick_section = false;

	// スクリプトヘッダ
	header_script = "";

	// プロトコルを判別
	if ( i_protocol=="SAORI" && i_protocol_version[0]>='1' )
	{
		o_protocol = i_protocol;
		o_protocol_version = "1.0";
		mRequestMode = SAORI;
	}
	else if ( i_protocol=="SHIORI" && i_protocol_version[0]>='3' )
	{
		mRequestMode = SHIORI3;
	}
	else if ( i_protocol=="SHIORI" && i_protocol_version[0]=='2' )
	{
		mRequestMode = SHIORI2;
			// 2.xにもバージョンとしては3.0を返す
	}
	else if ( i_protocol=="MAKOTO" && i_protocol_version[0]>='2' )
	{
		o_protocol = i_protocol;
		o_protocol_version = "2.0";
		mRequestMode = MAKOTO2;
	}
	else if ( i_protocol=="UNKNOWN" )
	{
		mRequestMode = UNKNOWN;
	}
	else
	{
		// 未対応のプロトコルだった。
		return	400;
	}

	// データ部をmRequestMapに格納。
	// SHOIRI/3.0以外のプロトコルの場合、SHOIRI/3.0に変換を行う。
	for ( strpairvec::const_iterator it = i_data.begin() ; it != i_data.end() ; ++it )
	{
		string key = it->first;
		const string& value = it->second;

		switch ( mRequestMode ) {
		case SAORI:
			if ( compare_head(key, "Argument") ) {
				int	n = stoi_internal(key.c_str()+8);
				if ( n==0 )
					key = "ID";
				else
					key = "Reference" + itos(n-1);
			}
			break;
		case SHIORI2:	// こっちはてきとー
			if ( key=="Event" )
				key="ID";
			break;
		case MAKOTO2:
			if ( key=="String" )
				key="Reference0";
			break;
		default:
			break;
		}

		mRequestMap[key] = value;
		if ( compare_head(key, "Reference") ) {
			int	n = stoi_internal(key.c_str()+9);
			if ( n>=0 && n<65536 ) {
				if ( n>=mReferences.size() )
					mReferences.resize(n+1);
				mReferences[n]=value;
			}
		}
	}

	if ( mRequestMode == MAKOTO2 )
	{
		mRequestMap["ID"] = "OnMakoto";
	}

	mRequestID = mRequestMap["ID"];
	mIsMateria = ( mRequestMap["Sender"] == "embryo" );
	mIsStatusHeaderExist = ( mRequestMap["Sender"] == "SSP" );

	//-------------------------------------------------
	// リクエストを解釈

	if ( mRequestCommand=="GET Version" )
	{
		if ( mRequestMode == SHIORI2 )
		{
			o_data.push_back( strpair("ID", gSatoriName) );
			o_data.push_back( strpair("Craftman", gSatoriCraftman) );
			o_data.push_back( strpair("Version", gSatoriVersion) );
		}
		return 200;
	}


	// 選択分岐記録を変数に代入。ref0を元に戻す。
	if ( compare_head(mRequestID, "OnChoice") ) // OnChoiceSelect/OnChoiceEnterの両方
	{
		strvec	vec;
		int	ref_no = ( mRequestID=="OnChoiceEnter" || mRequestID=="OnChoiceSelectEx" )?1:0;
		string&	info = mRequestMap[string("Reference")+itos(ref_no)];
		if ( split(info, byte1_dlmt, vec)==3 ) // \1区切りの3文字列であるならば
		{
			info=mReferences[ref_no]=variables["選択ID"]=vec[0];
			variables["選択ラベル"]=vec[1];
			variables["選択番号"]=vec[2];
		}
	}

	// ログについて色々
	bool log_disable_soft = ( mRequestID=="OnSurfaceChange" || mRequestID=="OnSecondChange" || mRequestID=="OnMinuteChange"
		|| mRequestID=="OnMouseMove" || mRequestID=="OnTranslate");

	bool log_disable_hard = ( /*compare_tail(mRequestID, "caption") || */compare_tail(mRequestID, "visible")
		|| compare_head(mRequestID, "menu.") || mRequestID.find(".color.")!=string::npos );

	GetSender().next_event();

	if(fRequestLog)
	{
		GetSender().sender() << "--- Request ---" << std::endl << mStatusLine <<std::endl; // << iRequest <<std::endl;
		for(strmap::const_iterator i=mRequestMap.begin() ; i!=mRequestMap.end() ; ++i)
			if ( !i->first.empty() && !i->second.empty()
				&& i->first!="SecurityLevel" 
				&& i->first!="Sender" 
				&& i->first!="Charset" ) {
				GetSender().sender() << i->first << ": " << i->second <<std::endl;
			}
	}

	// せきゅあ?
	strmap::const_iterator it = mRequestMap.find("SecurityLevel");
	secure_flag = ( it!=mRequestMap.end() && stricmp(it->second.c_str(), "local")==0 );

	// メイン処理
	GetSender().sender() << "--- Operation ---" << std::endl;

	int status_code = 500;
	if ( mRequestID=="enable_log" || mRequestID=="enable_debug" ) {
		if ( secure_flag ) {
			bool flag = false;
			if ( mReferences.size() > 0 ) {
				flag = atoi(mReferences[0].c_str()) != 0;
			}

			if ( mRequestID=="enable_debug" ) {
				fDebugMode = flag;
			}
			else {
				GetSender().validate(flag);
			}
			status_code = 200;
		}
		else {
			GetSender().sender() << "local/Localでないので蹴りました: ShioriEcho" <<std::endl;
			status_code = 403;
		}
	}
	else if ( mRequestID=="ShioriEcho" ) {
		// ShioriEcho実装
		if ( fDebugMode && secure_flag ) {
			string result = SentenceToSakuraScriptExec_with_PreProcess(mReferences);
			if ( result.length() ) {
				static const char* const dangerous_tag[] = {"\\![updatebymyself]",
					"\\![vanishbymyself]",
					"\\![enter,passivemode]",
					"\\![enter,inductionmode]",
					"\\![leave,passivemode]",
					"\\![leave,inductionmode]",
					"\\![lock,repaint]",
					"\\![unlock,repaint]",
					"\\![biff]",
					"\\![open,browser",
					"\\![open,mailer",
					"\\![raise",
					"\\j["};

				std::string replace_to;
				for ( int i = 0 ; i < (sizeof(dangerous_tag)/sizeof(dangerous_tag[0])) ; ++i ) {
					replace_to = "¥[";
					replace_to += dangerous_tag[i]+2; //\をヌキ
					replace(result,dangerous_tag[i],replace_to);
				}

				//Translate(result); - Translateは後でかかる
				mResponseMap["Value"] = result;
				status_code = 200;
			}
			else {
				status_code = 204;
			}
		}
		else {
			if ( fDebugMode ) {
				GetSender().sender() << "local/Localでないので蹴りました: ShioriEcho" <<std::endl;
				status_code = 403;
			}
			else {
				static const std::string dbgmsg = "デバッグモードが無効です。使用するためには$デバッグ=有効にしてください。: ShioriEcho";
				GetSender().sender() << dbgmsg <<std::endl;

				mResponseMap["Value"] = "\\0" + dbgmsg + "\\e";
				status_code = 200;
			}
		}
	}
	else if (mRequestID == "SatolistEcho"){
#ifndef POSIX
		// さとりすとデバッガ実装
		if (fDebugMode && secure_flag) {

			//R0は除去される
			strvec customRef;
			for (int i = 1; i < mReferences.size(); i++){
				customRef.push_back(mReferences[i]);
			}

			string result = SentenceToSakuraScriptExec_with_PreProcess(customRef);
			if (result.length()) {
				result = string("SSTP 200 OK\r\nCharset: Shift_JIS\r\nResult: ") + result + "\r\n\r\n";
			}
			else{
				//情報なし
				result = string("SSTP 204 No Content\r\nCharset: Shift_JIS\r\n\r\n");
			}

			char* copyData = new char[result.length() + 1];
			strcpy(copyData, result.c_str());

			COPYDATASTRUCT cds;
			cds.dwData = 0;
			cds.cbData = result.length() + 1;
			cds.lpData = copyData;
			DWORD ret;

			SendMessageTimeout((HWND)stoi_internal(mReferences[0]), WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds, 0, 1000, &ret);

			//ここで204を返すと非対応時のエラーを出すので200で通知メッセージを表示する
			status_code = 200;
			mResponseMap["Value"] = "\\0\\_q■情報を送信しました。\\e";
		}
		else {
			if (fDebugMode) {
				GetSender().sender() << "local/Localでないので蹴りました: SatolistEcho" <<std::endl;
				status_code = 403;
			}
			else {
				static const std::string dbgmsg = "デバッグモードが無効です。使用するためには$デバッグ=有効にしてください。: SatolistEcho";
				GetSender().sender() << dbgmsg <<std::endl;

				mResponseMap["Value"] = "\\0" + dbgmsg + "\\e";
				status_code = 200;
			}
		}
#endif // POSIX
	}
	else {
		status_code = CreateResponse(mResponseMap);
	}

	// 後処理1
	default_surface = next_default_surface;

	//--------------------------------------------------------------------

	// Valueに対する最終処理
	if ( status_code==200 ) {	// && compare_head(mRequestID, "On")
		strmap::iterator i = mResponseMap.find("Value");
		if ( i!=mResponseMap.end() ) {
			if ( return_empty ) {
				status_code = 204;
				mResponseMap.erase(i);
			}
			else {
				if ( !Translate(i->second) ) {
					status_code = 204;
					mResponseMap.erase(i);
				} 
				else {
					second_from_last_talk = 0;
					if ( compare_head(mRequestID, "On") ) {
						mResponseHistory.push_front(i->second);
						if ( mResponseHistory.size() >= RESPONSE_HISTORY_SIZE )
							mResponseHistory.pop_back();
					}
				}
			}
		}
	}

	GetSender().sender() << "status code : " << itos(status_code) <<std::endl;

	//--------------------------------------------------------------------

	for(strmap::const_iterator i=mResponseMap.begin() ; i!=mResponseMap.end() ; ++i)
	{
		string	key=i->first, value=i->second;

		switch ( mRequestMode ) {
		case SAORI:
			if ( key=="Value" ) {
				key = "Result";
				value = header_script + value;
			}
			else if ( compare_head(key, "Reference") ) {
				key = string() + "Value" + (key.c_str()+9);
			}
			break;
		case SHIORI2:
			if ( key=="Value" ) {
				key = "Sentence";
				value = header_script + value;
			}
			break;
		case MAKOTO2:
			if ( key=="Value" ) {
				key = "String";
				value = header_script + value;
			}
			break;
		default:
			if ( key=="Value" ) {
				value = header_script + value;
			}
			break;
		}
		o_data.push_back( strpair(key, value) );
	}

	if ( GetSender().errsender().get_log_mode() ) {
		const std::vector<string> &errlog = GetSender().errsender().get_log();

		std::string errmsg;
		std::string errlevel;

		for ( std::vector<string>::const_iterator itr = errlog.begin() ; itr != errlog.end(); ++itr ) {
			errmsg += "SATORI - ";
			errmsg += mRequestID;
			errmsg += " > ";
			errmsg += *itr;
			errmsg += "\1";
			errlevel += "critical\1";
		}

		if ( errmsg.length() ) {
			errmsg.erase(errmsg.end()-1,errmsg.end());
			errlevel.erase(errlevel.end()-1,errlevel.end());

			o_data.push_back( strpair("ErrorLevel",errlevel) );
			o_data.push_back( strpair("ErrorDescription",errmsg) );
		}
		GetSender().errsender().clear_log();
	}

	GetSender().validate();
	if(fResponseLog)
	{
		GetSender().sender() << "--- Response ---" <<std::endl << mResponseMap <<std::endl;
	}
	mResponseMap.clear();

	if ( log_disable_hard ) {
		GetSender().delete_last_request();
	}
	else if ( log_disable_soft ) {
		if ( status_code != 200 ) {
			GetSender().delete_last_request();
		}
	}

	GetSender().flush();

	//--------------------------------------------------------------------

	// リロード処理
	if ( reload_flag )
	{
		reload_flag = false;
		string	tmp = mBaseFolder;
		GetSender().sender() << "■■reloading." <<std::endl;
		unload();
		load(tmp);
		GetSender().sender() << "■■reloaded." <<std::endl;

		GetSender().flush();
	}

	return	status_code;
}
Esempio n. 4
0
string SakuraDLLHost::request(const string& i_request_string)
{
	//GetSender().sender() << "--- Request ---" << endl << i_request_string << endl;

	// HTTPもどき形式の要求文字列を解析する

	// restには未解釈の「残り」が入っている
	string rest = i_request_string;
	
	// 一行目を切り出し
	string command = cut_token(rest, CRLF);
	// 後ろから ' ' を探し、見つかればそれ以降をプロトコル部分として認識する
	string protocol, protocol_version;
	for ( int n = command.size()-1 ; n >= 0 ; --n )
	{
		if ( command[n] == ' ' )
		{
			protocol_version = command.substr(n+1); // いったん全部を預けて……
			protocol = cut_token(protocol_version, "/"); // /より前を取り出す。 /が無ければ全部貰い受ける
			command = command.substr(0, n);
			break;
		}
	}
	
	// 以降のデータ行を切り出し
	strpairvec data;
	while ( rest.size() > 0 )
	{
		string value = cut_token(rest, CRLF);
		string key = cut_token(value, ": ");
		data.push_back( strpair(key, value) );
	}
	
	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	
	// リクエストを実行する
	
	// 戻り値格納用オブジェクト
	string r_protocol, r_protocol_version;
	strpairvec r_data;
	
	int r_return_code = request(
		protocol, protocol_version, command, data, 
		r_protocol, r_protocol_version, r_data);

	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

	// 返答をHTTPもどき文字列形式として構築し、返す。
	
	string response;
	response += r_protocol + "/" + r_protocol_version + " ";
	
	switch ( r_return_code ) 
	{
	case 200: response += "200 OK"; break;
	case 204: response += "204 No Content"; break;
	case 400: response += "400 Bad Request"; break;
	default: response += "500 Internal Server Error"; break;
	}
	response += CRLF;

	// Charsetが無ければ付ける。
	bool charset_exists = false;
	for (strpairvec::const_iterator ite = r_data.begin(); ite != r_data.end(); ite++) {
	    if (ite->first == "Charset") {
			charset_exists = true;
			break;
	    }
	}
	if (!charset_exists) {
	    r_data.push_back(strpair("Charset", "Shift_JIS"));
	}
	
	for ( strpairvec::const_iterator i = r_data.begin() ; i != r_data.end() ; ++i )
	{
		response += i->first + ": " + i->second + CRLF;
	}
	response += CRLF;

	//GetSender().sender() << "--- Response ---" << endl << response << endl;
	return response;
}
Esempio n. 5
0
int CodeWriter::initStyle(std::string stylefile)
{	
	const unsigned int BUFFERSIZE = 300;
	char buf[BUFFERSIZE];

	// 버퍼 초기화 
    memset(buf, BUFFERSIZE, 0);
	char delim[] = "\n";
    char *ptr;
	bool flag = false;

	//std::string stylefileFullname = m_homeDir + "/" + stylefile;
	std::string stylefileFullname = stylefile;
	m_file_style = fopen(stylefileFullname.c_str(), "r");
	if(m_file_style == NULL) return -1;

	//패턴파일을 한줄씩 읽으면서
    while(fgets(buf, BUFFERSIZE, m_file_style) != NULL) {     
		// 문자열 분리하여 출력하기
		ptr = (char*)strtok(buf, delim);		
		
		if(ptr==NULL){
			//printf("\n");
		}
		else{
			//printf("%s\n", ptr);
			std::string line = Estring::trim(std::string(ptr));
			if(line=="$start_inline"){
				flag = true;
			}
			else if(line=="$end_inline")
				break;
			else if(line==""){
				//공백라인인 경우
			}
			else if(flag){			
				std::vector<std::string> sline = Estring::split(line, "@");
				std::string key = Estring::trim(sline[0]);
				std::string elem = sline[1];
				if(key!="" && elem != "")

					//블록인 경우
					if(Estring::trim(elem) == "$start_block"){										
						elem = "";
						std::string end = "$end_block";
						while(1){
							fgets(buf, BUFFERSIZE, m_file_style);
							ptr = (char*)strtok(buf, delim);
							if(ptr != NULL){
								if(end.compare( Estring::trim(ptr))==0) break;
								elem.append(ptr);							
							}
							elem.append("\n");
						}
					}
					
					//삽입
					m_ptable.insert(strpair(key, elem));
			}
		}
		memset(buf, BUFFERSIZE, 0);
    }	
	fclose(m_file_style);
	return 0;
}