pion-net  4.0.9
EchoService.cpp
1 // ------------------------------------------------------------------
2 // pion-net: a C++ framework for building lightweight HTTP interfaces
3 // ------------------------------------------------------------------
4 // Copyright (C) 2007-2008 Atomic Labs, Inc. (http://www.atomiclabs.com)
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // See http://www.boost.org/LICENSE_1_0.txt
8 //
9 
10 #include "EchoService.hpp"
11 #include <boost/bind.hpp>
12 #include <pion/PionAlgorithms.hpp>
13 #include <pion/net/HTTPResponseWriter.hpp>
14 #include <pion/net/PionUser.hpp>
15 
16 using namespace pion;
17 using namespace pion::net;
18 
19 namespace pion { // begin namespace pion
20 namespace plugins { // begin namespace plugins
21 
22 
24 void writeDictionaryTerm(HTTPResponseWriterPtr& writer,
25  const HTTPTypes::QueryParams::value_type& val,
26  const bool decode)
27 {
28  // text is copied into writer text cache
29  writer << val.first << HTTPTypes::HEADER_NAME_VALUE_DELIMITER
30  << (decode ? algo::url_decode(val.second) : val.second)
31  << HTTPTypes::STRING_CRLF;
32 }
33 
34 
35 // EchoService member functions
36 
38 void EchoService::operator()(HTTPRequestPtr& request, TCPConnectionPtr& tcp_conn)
39 {
40  // this web service uses static text to test the mixture of "copied" with
41  // "static" (no-copy) text
42  static const std::string REQUEST_ECHO_TEXT("[Request Echo]");
43  static const std::string REQUEST_HEADERS_TEXT("[Request Headers]");
44  static const std::string QUERY_PARAMS_TEXT("[Query Parameters]");
45  static const std::string COOKIE_PARAMS_TEXT("[Cookie Parameters]");
46  static const std::string POST_CONTENT_TEXT("[POST Content]");
47  static const std::string USER_INFO_TEXT("[USER Info]");
48 
49  // Set Content-type to "text/plain" (plain ascii text)
50  HTTPResponseWriterPtr writer(HTTPResponseWriter::create(tcp_conn, *request,
51  boost::bind(&TCPConnection::finish, tcp_conn)));
52  writer->getResponse().setContentType(HTTPTypes::CONTENT_TYPE_TEXT);
53 
54  // write request information
55  writer->writeNoCopy(REQUEST_ECHO_TEXT);
56  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
57  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
58  writer
59  << "Request method: "
60  << request->getMethod()
61  << HTTPTypes::STRING_CRLF
62  << "Resource originally requested: "
63  << request->getOriginalResource()
64  << HTTPTypes::STRING_CRLF
65  << "Resource delivered: "
66  << request->getResource()
67  << HTTPTypes::STRING_CRLF
68  << "Query string: "
69  << request->getQueryString()
70  << HTTPTypes::STRING_CRLF
71  << "HTTP version: "
72  << request->getVersionMajor() << '.' << request->getVersionMinor()
73  << HTTPTypes::STRING_CRLF
74  << "Content length: "
75  << (unsigned long)request->getContentLength()
76  << HTTPTypes::STRING_CRLF
77  << HTTPTypes::STRING_CRLF;
78 
79  // write request headers
80  writer->writeNoCopy(REQUEST_HEADERS_TEXT);
81  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
82  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
83  std::for_each(request->getHeaders().begin(), request->getHeaders().end(),
84  boost::bind(&writeDictionaryTerm, writer, _1, false));
85  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
86 
87  // write query parameters
88  writer->writeNoCopy(QUERY_PARAMS_TEXT);
89  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
90  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
91  std::for_each(request->getQueryParams().begin(), request->getQueryParams().end(),
92  boost::bind(&writeDictionaryTerm, writer, _1, true));
93  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
94 
95  // write cookie parameters
96  writer->writeNoCopy(COOKIE_PARAMS_TEXT);
97  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
98  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
99  std::for_each(request->getCookieParams().begin(), request->getCookieParams().end(),
100  boost::bind(&writeDictionaryTerm, writer, _1, false));
101  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
102 
103  // write POST content
104  writer->writeNoCopy(POST_CONTENT_TEXT);
105  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
106  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
107  if (request->getContentLength() != 0) {
108  writer->write(request->getContent(), request->getContentLength());
109  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
110  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
111  }
112 
113  // if authenticated, write user info
114  PionUserPtr user = request->getUser();
115  if (user) {
116  writer->writeNoCopy(USER_INFO_TEXT);
117  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
118  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
119  writer << "User authenticated, username: " << user->getUsername();
120  writer->writeNoCopy(HTTPTypes::STRING_CRLF);
121  }
122 
123  // send the writer
124  writer->send();
125 }
126 
127 
128 } // end namespace plugins
129 } // end namespace pion
130 
131 
133 extern "C" PION_SERVICE_API pion::plugins::EchoService *pion_create_EchoService(void)
134 {
135  return new pion::plugins::EchoService();
136 }
137 
139 extern "C" PION_SERVICE_API void pion_destroy_EchoService(pion::plugins::EchoService *service_ptr)
140 {
141  delete service_ptr;
142 }