# net/services/CookieService.cpp

    00001 // ------------------------------------------------------------------
    00002 // pion-net: a C++ framework for building lightweight HTTP interfaces
    00003 // ------------------------------------------------------------------
    00004 // Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
    00005 //
    00006 // Distributed under the Boost Software License, Version 1.0.
    00007 // See http://www.boost.org/LICENSE_1_0.txt
    00008 //
    00009
    00010 #include "CookieService.hpp"
    00011 #include <pion/PionAlgorithms.hpp>
    00012 #include <pion/net/HTTPResponseWriter.hpp>
    00013
    00014 using namespace pion;
    00015 using namespace pion::net;
    00016
    00017 namespace pion {        // begin namespace pion
    00018 namespace plugins {     // begin namespace plugins
    00019
    00020
    00021 // CookieService member functions
    00022
    00024 void CookieService::operator()(HTTPRequestPtr& request, TCPConnectionPtr& tcp_conn)
    00025 {
    00026     static const std::string HEADER_HTML = "<html>\n<head>\n<title>Cookie Service</title>\n"
    00027         "</head>\n<body>\n\n<h1>Cookie Service</h1>\n";
    00028     static const std::string FOOTER_HTML = "\n</body>\n</html>\n";
    00029
    00030     // Set Content-type for HTML and write the header
    00031     HTTPResponseWriterPtr writer(HTTPResponseWriter::create(tcp_conn, *request,
    00032                                                             boost::bind(&TCPConnection::finish, tcp_conn)));
    00033     writer->getResponse().setContentType(HTTPTypes::CONTENT_TYPE_HTML);
    00034     writer->writeNoCopy(HEADER_HTML);
    00035
    00036     // Check if we have an action to perform
    00037     if (request->hasQuery("action")) {
    00038         if (algo::url_decode(request->getQuery("action")) == "Add Cookie") {
    00039             // add a new cookie
    00040             const std::string cookie_name(request->getQuery("cookie_name"));
    00041             const std::string cookie_value(request->getQuery("cookie_value"));
    00042             if (cookie_name.empty() || cookie_value.empty()) {
    00043                 writer << "\n<p>[Error: You must specify a name and value to add a cookie]</p>\n\n";
    00044             } else {
    00045                 writer->getResponse().setCookie(cookie_name, cookie_value);
    00046                 writer << "\n<p>[Added cookie "
    00047                     << cookie_name << '=' << cookie_value << "]</p>\n\n";
    00048             }
    00049         } else if (request->getQuery("action") == "delete") {
    00050             const std::string cookie_name(request->getQuery("cookie_name"));
    00051             if (cookie_name.empty()) {
    00052                 writer << "\n<p>[Error: You must specify a name to delete a cookie]</p>\n\n";
    00053             } else {
    00054                 writer->getResponse().deleteCookie(cookie_name);
    00055                 writer << "\n<p>[Deleted cookie " << cookie_name << "]</p>\n\n";
    00056             }
    00057         } else {
    00058             writer << "\n<p>[Error: Unrecognized action]</p>\n\n";
    00059         }
    00060     }
    00061
    00062     // display cookie headers in request
    00063     if (request->hasHeader(HTTPTypes::HEADER_COOKIE)) {
    00064         writer << "\n<h2>Cookie Headers</h2>\n<ul>\n";
    00065         std::pair<HTTPTypes::Headers::const_iterator, HTTPTypes::Headers::const_iterator>
    00066             header_pair = request->getHeaders().equal_range(HTTPTypes::HEADER_COOKIE);
    00067         for (HTTPTypes::Headers::const_iterator header_iterator = header_pair.first;
    00068              header_iterator != request->getHeaders().end()
    00069              && header_iterator != header_pair.second; ++header_iterator)
    00070         {
    00071             writer << "<li>Cookie: " << header_iterator->second << "\n";
    00072         }
    00073         writer << "</ul>\n\n";
    00074     } else {
    00075         writer << "\n<h2>No Cookie Headers</h2>\n\n";
    00076     }
    00077
    00078     // display existing cookies
    00079     HTTPTypes::CookieParams& cookie_params = request->getCookieParams();
    00080     if (! cookie_params.empty()) {
    00081         writer << "\n<h2>Cookie Variables</h2>\n<ul>\n";
    00082         for (HTTPTypes::CookieParams::const_iterator i = cookie_params.begin();
    00083              i != cookie_params.end(); ++i)
    00084         {
    00085             writer << "<li>" << i->first << ": " << i->second
    00086                 << " <a href=\"" << request->getResource()
    00087                 << "?action=delete&cookie_name=" << i->first
    00088                 << "\">[Delete]</a>\n";
    00089         }
    00090         writer << "</ul>\n\n";
    00091     } else {
    00092         writer << "\n<h2>No Cookie Variables</h2>\n\n";
    00093     }
    00094
    00095     // display form to add a cookie
    00096     writer << "\n<h2>Add Cookie</h2>\n"
    00097         "<p><form action=\"" << request->getResource() << "\" method=\"POST\">\n"
    00098         "Name: <input type=\"text\" name=\"cookie_name\"><br />\n"
    00099         "Value: <input type=\"text\" name=\"cookie_value\"><br />\n"
    00100         "<input type=\"submit\" name=\"action\" value=\"Add Cookie\"></p>\n"
    00101         "</form>\n\n";
    00102
    00103     // write the footer
    00104     writer->writeNoCopy(FOOTER_HTML);
    00105
    00106     // send the writer
    00107     writer->send();
    00108 }
    00109
    00110
    00111 }   // end namespace plugins
    00112 }   // end namespace pion
    00113
    00114
    00116 extern "C" PION_SERVICE_API pion::plugins::CookieService *pion_create_CookieService(void)
    00117 {
    00118     return new pion::plugins::CookieService();
    00119 }
    00120
    00122 extern "C" PION_SERVICE_API void pion_destroy_CookieService(pion::plugins::CookieService *service_ptr)
    00123 {
    00124     delete service_ptr;
    00125 }