/* ZazouMiniWebServer Copyright (C) 2003-2011 Xavier Garreau This file is part of ZazouMiniWebServer. ZazouMiniWebServer is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. ZazouMiniWebServer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with ZazouMiniWebServer; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ // ZMWSReqResp.cpp: implementation of the ZMWSReqResp class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZMWSReqResp.h" #include "ZMWSFileUtils.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// ZMWSReqResp::ZMWSReqResp(SOCKET* sock) { retCode = 200; status = NONE; pClientSocket = NULL; pFileHandle = NULL; bytesSent_HI = 0; bytesSent_LO = 0; cnx_policy = CNX_POLICY_KEEP; isDir = FALSE; isSSL = FALSE; aliasRootDir = ""; } ZMWSReqResp::~ZMWSReqResp() { reqvars.clear(); respvars.clear(); } BOOL ZMWSReqResp::addSentBytes(const DWORD& moreBytes) { if (bytesSent_LO + moreBytes < bytesSent_LO) ++bytesSent_HI; bytesSent_LO += moreBytes; return TRUE; } const std::string ZMWSReqResp::setRespVar(const std::string& varName, const std::string& varVal, const BOOL& Override) { std::string retString(""); if (Override) { // retString = respvars[varName]; respvars[varName] = varVal; } else { if (respvars.find(varName) != respvars.end()) { retString = respvars[varName]; } else { respvars[varName] = varVal; } } return retString; } const std::string ZMWSReqResp::getRespVar(const std::string& varName) { std::string retString(""); if (respvars.find(varName) != respvars.end()) { retString = respvars[varName]; } return retString; } void ZMWSReqResp::eraseRespVar(const std::string& varName) { respvars.erase(varName); } const std::string ZMWSReqResp::setReqVar(const std::string& varName, const std::string& varVal, const BOOL& Override) { std::string retString(""); if (Override) { // retString = reqvars[varName]; reqvars[varName] = varVal; } else { if (reqvars.find(varName) != reqvars.end()) { retString = reqvars[varName]; } else { reqvars[varName] = varVal; } } if (varName=="RANGE") UpdateRanges(varVal); return retString; } const std::string ZMWSReqResp::getReqVar(const std::string& varName) { std::string retString(""); if (reqvars.find(varName) != reqvars.end()) { retString = reqvars[varName]; } return retString; } void ZMWSReqResp::setURL(const std::string& value) { std::string urlmin; urlmin = value; std::transform(urlmin.begin(), urlmin.end(), urlmin.begin(), tolower); if (urlmin.substr(0, 7)=="http://") { std::string::size_type lastslash = urlmin.find('/', 7); if (lastslash != std::string::npos) { URL = value.substr(lastslash); setReqVar("HOST", value.substr(7, lastslash-7)); } else { URL = '/'; setReqVar("HOST", value.substr(7)); } } else { URL = value; } } void ZMWSReqResp::setFilePath(const std::string& value) { // get rid of a trailing slash filePath = value; ZMWSFileUtils::normalizePath(filePath); std::string::size_type len = filePath.length(); DWORD nbOff = 0; while (filePath[len-(1+nbOff)]=='\\') { ++nbOff; } filePath = (filePath.substr(0, len-nbOff)); } void ZMWSReqResp::addLang(const std::string& alang, const double& aqual) { langs_map.insert (lang_pair_type (aqual, alang)); } std::string ZMWSReqResp::RemovePort(const std::string& HOSTvar) { std::string host; std::string::size_type hostend = HOSTvar.rfind(':'); if (hostend != std::string::npos) host = HOSTvar.substr(0, hostend); else host = HOSTvar; return host; } std::string ZMWSReqResp::ComputeDate(SYSTEMTIME& st) { std::stringstream dateS; switch (st.wDayOfWeek) { case 0: dateS << "Sun, "; break; case 1: dateS << "Mon, "; break; case 2: dateS << "Tue, "; break; case 3: dateS << "Wed, "; break; case 4: dateS << "Thu, "; break; case 5: dateS << "Fri, "; break; case 6: dateS << "Sat, "; break; default: return ""; } if (st.wDay<10) dateS << "0"; dateS << st.wDay; switch (st.wMonth) { case 1: dateS << " Jan "; break; case 2: dateS << " Feb "; break; case 3: dateS << " Mar "; break; case 4: dateS << " Apr "; break; case 5: dateS << " May "; break; case 6: dateS << " Jun "; break; case 7: dateS << " Jul "; break; case 8: dateS << " Aug "; break; case 9: dateS << " Sep "; break; case 10: dateS << " Oct "; break; case 11: dateS << " Nov "; break; case 12: dateS << " Dec "; break; default: return ""; } if (st.wYear<1000) dateS << "0"; if (st.wYear<100) dateS << "0"; if (st.wYear<10) dateS << "0"; dateS << st.wYear << " "; if (st.wHour<10) dateS << "0"; dateS << st.wHour << ":"; if (st.wMinute<10) dateS << "0"; dateS << st.wMinute << ":"; if (st.wSecond<10) dateS << "0"; dateS << st.wSecond << " GMT"; return dateS.str(); } void ZMWSReqResp::UpdateRanges(const std::string& RangeReq) { // On vire "bytes=" std::string varRangeReq = RangeReq.substr(6); std::string::size_type tiret_pos = varRangeReq.find("-"); std::string::size_type virgule_pos = varRangeReq.find(","); // On ignore les range multiples pour l'instant if (virgule_pos != std::string::npos) return; if (tiret_pos != std::string::npos) { if (tiret_pos > 0) { // on a un byte range unsigned long first_byte, last_byte; std::string first_byte_str, last_byte_str; first_byte_str = varRangeReq.substr(0, tiret_pos); first_byte = strtoul(first_byte_str.c_str(), NULL, 10); if (tiret_pos < varRangeReq.length()-1) { last_byte_str = varRangeReq.substr(tiret_pos + 1); last_byte = strtoul(last_byte_str.c_str(), NULL, 10); ranges.push_back(ZMWSRange(first_byte, last_byte)); } else { ranges.push_back(ZMWSRange(first_byte, 0, ZMWSRange::PREFIX_BYTE_RANGE_SPEC)); } } else { // on a un suffix byte range unsigned long last_n_bytes; std::string last_n_bytes_str; last_n_bytes_str = varRangeReq.substr(tiret_pos + 1); last_n_bytes = strtoul(last_n_bytes_str.c_str(), NULL, 10); ranges.push_back(ZMWSRange(0, last_n_bytes, ZMWSRange::SUFFIX_BYTE_RANGE_SPEC)); } } } ZMWSRange ZMWSReqResp::popRangeReq() { ZMWSRange retRange; if (ranges.size()) { retRange = ranges.back(); ranges.pop_back(); } return retRange; } void ZMWSReqResp::pushContentRangeResp(ZMWSContentRange range) { content_ranges.push_back(range); } ZMWSContentRange ZMWSReqResp::popContentRangeResp() { ZMWSContentRange retRange; if (content_ranges.size()) { retRange = content_ranges.back(); content_ranges.pop_back(); } return retRange; }