CPPSERV


Home Projects Jobs Clientele Contact
CPPSERV Documentation Download TODO Mailing lists Bug tracker News RSS Feed Browse source

HttpServletResponseImpl.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2004 by Ilya A. Volynets-Evenbakh                       *
00003  *   ilya@total-knowledge.com                                              *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 #include <HttpServletResponseImpl.h>
00021 #include <servlet/IllegalStateException.h>
00022 #include <servlet/ServletException.h>
00023 
00024 #include <sstream>
00025 
00026 namespace container {
00027 
00028 HttpServletResponseImpl::HttpServletResponseImpl(Connection& con, const std::string& mimeType, const std::string& charEnc)
00029     : m_req(0)
00030     , m_contentLength(-1)
00031     , m_contentType(mimeType)
00032     , m_characterEncoding(charEnc)
00033     , m_outputStream(con,*this)
00034     , m_committed(false)
00035     , m_statusCode(SC_OK)
00036 {
00037 }
00038 
00039 
00040 HttpServletResponseImpl::~HttpServletResponseImpl()
00041 {
00042 }
00043 
00050 void HttpServletResponseImpl::sendHeaders(Connection& c)
00051 {
00052     std::ostream con(&c);
00053     std::string ct = getContentType();
00054     if(!getCharacterEncoding().empty())
00055         ct+="; charset="+getCharacterEncoding();
00056     setHeader(std::string("content-type"),ct);
00057     //con<<"HTTP/1.1 "<<statusCode<<' '<<getStatusMessage()<<'\n';
00058     con<<"Status: "<<m_statusCode<<'\n';
00059     if(m_contentLength!=-1)
00060         con<<"Content-length: "<<m_contentLength<<'\n';
00061     for(util::mparam_t::iterator cur=m_headers.begin(); cur!=m_headers.end(); cur++)
00062         con<<cur->first<<": "<<cur->second<<'\n';
00063     //Send cookies now
00064     for(cookielist_t::iterator curC=m_cookies.begin(); curC!=m_cookies.end(); curC++){
00065         std::stringstream cookieStr;
00066         time_t maxAge=curC->getMaxAge();
00067         cookieStr<<curC->getName()<<'='<<quoteString(curC->getValue());
00068         if(!curC->getDomain().empty())
00069             cookieStr<<"; Domain="<<quoteString(curC->getDomain());
00070         if(!curC->getPath().empty())
00071             cookieStr<<"; Path="<<quoteString(curC->getPath());
00072         if(curC->getSecure())
00073             cookieStr<<"; Secure;";
00074         if(curC->getVersion()!=0){
00075             cookieStr<<"; Version="<<curC->getVersion();
00076             if(!curC->getComment().empty())
00077                 cookieStr<<"; Comment="<<quoteString(curC->getComment());
00078             if(maxAge>=0)
00079                 cookieStr<<"; Max-Age="<<maxAge;
00080         }else{
00081             if(maxAge>=0) {
00082                 char date[32];
00083                 struct tm exp;
00084                 maxAge=maxAge?maxAge+::time(0):1;
00085                 ::gmtime_r(&maxAge, &exp);
00086                 ::strftime(date, sizeof(date), "\"%a, %d-%m-%Y %H:%M:%S %Z\"", &exp);
00087                 cookieStr<<"; Expires="<<date;
00088             }
00089         }
00090         con<<"Set-Cookie: "<<cookieStr.str()<<'\n';
00091         std::cerr<<"Set-Cookie: "<<cookieStr.str()<<std::endl;
00092     }
00093     con<<'\n';
00094     m_committed=true;
00095 }
00096 
00097 std::string HttpServletResponseImpl::quoteString(const std::string& in)
00098 {
00099     std::string out;
00100     if(in.empty())
00101         out="\"\"";
00102     else if(in.find_first_of(",; \"")!=std::string::npos)
00103     {
00104         out.reserve(in.length()+2);
00105         out+='"';
00106         for(std::string::size_type i=0; i<in.length(); i++)
00107         {
00108             if(in[i]=='"')
00109                 out+="\\\"";
00110             else
00111                 out+=in[i];
00112         }
00113         out+='"';
00114     }
00115     else
00116         out.assign(in);
00117     return out;
00118 }
00119 
00120 }
00121 
00125 void container::HttpServletResponseImpl::flushBuffer()
00126 {
00127     getOutputStream().flush();
00128 }
00129 
00130 
00134 void container::HttpServletResponseImpl::reset()
00135 {
00136     resetBuffer();// Will throw servlet::IllegalStateException if isCommitted()
00137     m_headers.clear();
00138     m_cookies.clear();
00139     setContentType("text/html");
00141 }
00142 
00143 
00151 void container::HttpServletResponseImpl::resetBuffer()
00152 {
00153     if(isCommitted())
00154         throw servlet::IllegalStateException();
00156 }
00157 
00158 
00162 void container::HttpServletResponseImpl::addHeader(const std::string& name, const std::string& value)
00163 {
00164     if(isCommitted())
00165         throw servlet::IllegalStateException();
00166 
00167     std::string lname(name);
00168     std::transform(lname.begin(),lname.end(),lname.begin(),::tolower);
00169     m_headers.insert(util::nvpair(lname,value));
00170 }
00171 
00172 void container::HttpServletResponseImpl::setHeader(const std::string& name, const std::string& value)
00173 {
00174     if(isCommitted())
00175         throw servlet::IllegalStateException();
00176 
00177     std::string lname(name);
00178     std::transform(lname.begin(),lname.end(),lname.begin(),::tolower);
00179     m_headers.erase(m_headers.lower_bound(lname),m_headers.upper_bound(lname));
00180     m_headers.insert(util::nvpair(name,value));
00181 }
00182 
00186 bool container::HttpServletResponseImpl::containsHeader(const std::string& name) const
00187 {
00188     std::string lname(name);
00189     std::transform(lname.begin(),lname.end(),lname.begin(),::tolower);
00190     return m_headers.find(lname)!=m_headers.end();
00191 }
00192 
00193 
00197 void container::HttpServletResponseImpl::setStatus(int sc)
00198 {
00199     if(isCommitted())
00200         throw servlet::IllegalStateException();
00201 
00202     m_statusCode=sc;
00203 }
00204 
00205 
00209 void container::HttpServletResponseImpl::sendRedirect(const std::string& location)
00210 {
00211     if(isCommitted())
00212         throw servlet::IllegalStateException();
00213     // Send location header
00214     sendError(SC_SEE_OTHER);
00215     addHeader("Location",location);
00216     //Commit...
00217     getOutputStream()<<"\n";
00218 }
00219 
00220 
00224 void container::HttpServletResponseImpl::sendError(int sc)
00225 {
00226     if(isCommitted())
00227         throw servlet::IllegalStateException();
00228 
00229     m_statusMsg.clear();
00230     m_statusCode=sc;
00231 }
00232 
00233 
00237 void container::HttpServletResponseImpl::sendError(int sc, const std::string& msg)
00238 {
00239     if(isCommitted())
00240         throw servlet::IllegalStateException();
00241 
00242     m_statusCode=sc;
00243     m_statusMsg=msg;
00244 }
00245 
00246 
00250 std::string container::HttpServletResponseImpl::getStatusMessage()
00251 {
00252     if(!m_statusMsg.empty())
00253         return m_statusMsg;
00254     switch(m_statusCode){
00255     case SC_OK:
00256         return std::string("OK");
00257     case SC_NOT_FOUND:
00258         return std::string("Servlet is not defined");
00259     default:
00260         return std::string("No message");
00261     }
00262 }
00263 
00264 
00268 void container::HttpServletResponseImpl::addCookie(const servlet::Cookie& cookie)
00269 {
00270     if(isCommitted()){
00271         throw servlet::IllegalStateException();
00272     }
00273     m_cookies.push_back(cookie);
00274 }
00275 
00276 namespace container
00277 {
00278 std::string  HttpServletResponseImpl::getCharacterEncoding()
00279 {
00280     return m_characterEncoding;
00281 }
00282 std::string  HttpServletResponseImpl::getContentType()
00283 {
00284     return m_contentType;
00285 }
00286 std::ostream&  HttpServletResponseImpl::getOutputStream()
00287 {
00288     return m_outputStream;
00289 }
00290 void  HttpServletResponseImpl::setCharacterEncoding(const std::string& charset)
00291 {
00292     if(isCommitted()){
00293         throw servlet::IllegalStateException();
00294     }
00295     m_characterEncoding = charset;
00296 }
00297 void  HttpServletResponseImpl::setContentLength(int len)
00298 {
00299     if(isCommitted()){
00300         throw servlet::IllegalStateException();
00301     }
00302     m_contentLength = len;
00303 }
00304 void  HttpServletResponseImpl::setContentType(const std::string& type)
00305 {
00306     if(isCommitted()){
00307         throw servlet::IllegalStateException();
00308     }
00309     m_contentType = type;
00310 }
00311 void  HttpServletResponseImpl::setBufferSize(int size)
00312 {
00313     m_outputStream.setBufferSize(size);
00314 }
00315 int  HttpServletResponseImpl::getBufferSize()
00316 {
00317     return m_outputStream.getBufferSize();
00318 }
00319 bool  HttpServletResponseImpl::isCommitted()
00320 {
00321     return m_committed;
00322 }
00323 
00325 std::string  HttpServletResponseImpl::encodeURL(const std::string& url)
00326 {
00327     //FIXME: implement this for real...
00328     return url;
00329 }
00330 std::string  HttpServletResponseImpl::encodeRedirectURL(const std::string& url)
00331 {
00332     //FIXME: implement this for real...
00333     return url;
00334 }
00335 void  HttpServletResponseImpl::setDateHeader(const std::string& name, long date)
00336 {
00337     struct tm out;
00338     gmtime_r(&date, &out);
00339     char str[32];
00340     strftime(str, sizeof(str), "%a, %d %b %Y %H:%M:%S GMT", &out);
00341     setHeader(name, str);
00342 }
00343 void  HttpServletResponseImpl::addDateHeader(const std::string& name, long date)
00344 {
00345     struct tm out;
00346     gmtime_r(&date, &out);
00347     char str[32];
00348     strftime(str, sizeof(str), "%a, %d %b %Y %H:%M:%S GMT", &out);
00349     addHeader(name, str);
00350 }
00351 void  HttpServletResponseImpl::setIntHeader(const std::string& name, int value)
00352 {
00353     std::stringstream val;
00354     val<<value;
00355     setHeader(name, val.str());
00356 }
00357 void  HttpServletResponseImpl::addIntHeader(const std::string& name, int value)
00358 {
00359     std::stringstream val;
00360     val<<value;
00361     addHeader(name, val.str());
00362 }
00363 }

SourceForge.net Logo