Pol  Revision:cb584c9
httpmod.cpp
Go to the documentation of this file.
1 
6 #include "httpmod.h"
7 
8 #include "../../bscript/berror.h"
9 #include "../../bscript/impstr.h"
10 #include "../../clib/logfacility.h"
11 #include "../../clib/wnsckt.h"
12 #include "../../plib/systemstate.h"
13 #include "../uoexec.h"
14 #include "osmod.h"
15 
16 
17 namespace Pol
18 {
19 namespace Core
20 {
21 std::string http_decodestr( const std::string& s );
22 }
23 namespace Bscript
24 {
25 using namespace Module;
26 template <>
29  {"WriteHtml", &HttpExecutorModule::mf_WriteHtml},
30  {"WriteHtmlRaw", &HttpExecutorModule::mf_WriteHtmlRaw},
31  {"QueryParam", &HttpExecutorModule::mf_QueryParam},
32  {"QueryIP", &HttpExecutorModule::mf_QueryIP},
33 };
34 }
35 namespace Module
36 {
37 using namespace Bscript;
38 
40  : Bscript::TmplExecutorModule<HttpExecutorModule>( "http", exec ),
41  sck_( isck ),
42  continuing_offset( 0 ),
43  uoexec( static_cast<Core::UOExecutor&>( exec ) )
44 {
45 }
46 
48 {
49  const String* str;
50  if ( !sck_.connected() )
51  {
52  exec.seterror( true );
53  return new BError( "Socket is disconnected" );
54  }
55  if ( getStringParam( 0, str ) )
56  {
57  // TODO: some tricky stuff so if the socket blocks, the script goes to
58  // sleep for a bit and sends the rest later
59 
60  unsigned nsent;
61  const std::string& s = str->value();
62  bool res =
63  sck_.send_nowait( (void*)( s.c_str() + continuing_offset ),
64  static_cast<unsigned int>( s.length() - continuing_offset ), &nsent );
65  if ( res )
66  {
68  // we don't really care if this works or not, terribly.
69  sck_.send_nowait( "\n", 1, &nsent );
70  return new BLong( 1 );
71  }
72  else
73  {
74  continuing_offset += nsent;
75  uoexec.os_module->SleepForMs( 500 );
76  --uoexec.PC;
77  return uoexec.fparams[0]->impptr();
78  }
79  }
80  else
81  {
82  return new BError( "Invalid parameter type" );
83  }
84 }
85 
87 {
88  const String* str;
89  if ( !sck_.connected() )
90  {
91  exec.seterror( true );
92  return new BError( "Socket is disconnected" );
93  }
94  exec.makeString( 0 );
95  if ( getStringParam( 0, str ) )
96  {
97  // TODO: some tricky stuff so if the socket blocks, the script goes to
98  // sleep for a bit and sends the rest later
99 
100  unsigned nsent;
101  const std::string& s = str->value();
102  bool res =
103  sck_.send_nowait( (void*)( s.c_str() + continuing_offset ),
104  static_cast<unsigned int>( s.length() - continuing_offset ), &nsent );
105  if ( res )
106  {
107  continuing_offset = 0;
108  return new BLong( 1 );
109  }
110  else
111  {
112  continuing_offset += nsent;
113  uoexec.os_module->SleepForMs( 500 );
114  --uoexec.PC;
115  return uoexec.fparams[0]->impptr();
116  }
117  }
118  else
119  {
120  return new BError( "Invalid parameter type" );
121  }
122 }
123 
124 #if 0
126  {
127  const String* str;
128  if (getStringParam( 0, str ))
129  {
130  // TODO: some tricky stuff so if the socket blocks, the script goes to
131  // sleep for a bit and sends the rest later
132  http_writeline( sck_, str->value() );
133  return new BLong(1);
134  }
135  else
136  {
137  return new BError( "Invalid parameter type" );
138  }
139  }
140 #endif
141 
143 {
144  const String* str;
145  if ( getStringParam( 0, str ) )
146  {
147  QueryParamMap::iterator itr = params_.find( str->data() );
148  if ( itr != params_.end() )
149  return new String( ( *itr ).second );
150  else
151  return new BLong( 0 );
152  }
153  else
154  {
155  return new BError( "Invalid parameter type" );
156  }
157 }
158 
160 {
161  return new String( query_ip_ );
162 }
163 
164 
165 // query_string is everything after the '?'
166 void HttpExecutorModule::read_query_string( const std::string& query_string )
167 {
168  if ( !query_string.empty() )
169  {
170  std::string::size_type brk;
171  std::string::size_type start = 0;
172  do
173  {
174  brk = query_string.find( '&', start );
175  std::string param =
176  query_string.substr( start, ( brk == std::string::npos ) ? brk : brk - start );
177 
178  std::string name, value;
179  std::string::size_type eq = param.find( '=' );
180  if ( eq != std::string::npos )
181  {
182  name = param.substr( 0, eq );
183  value = Core::http_decodestr( param.substr( eq + 1 ) );
184  }
185  else
186  {
187  name = param;
188  value = "";
189  }
190  params_[name.c_str()] = value;
191 
192  if ( Plib::systemstate.config.web_server_debug )
193  INFO_PRINT << "http-param: '" << param << "', '" << Core::http_decodestr( param ) << "'\n";
194 
195  start = brk + 1;
196  } while ( brk != std::string::npos );
197  }
198 }
199 
201 {
203 }
204 }
205 }
const std::string & value() const
Definition: impstr.h:67
Bscript::BObjectImp * mf_QueryParam()
Definition: httpmod.cpp:142
Core::UOExecutor & uoexec
Definition: httpmod.h:51
SystemState systemstate
Definition: systemstate.cpp:12
bool connected() const
Definition: wnsckt.cpp:308
void seterror(bool err)
Definition: executor.h:437
int makeString(unsigned param)
Definition: executor.cpp:196
Bscript::BObjectImp * mf_QueryIP()
Definition: httpmod.cpp:159
std::string getpeername() const
Definition: wnsckt.cpp:92
Bscript::BObjectImp * mf_WriteHtmlRaw()
Definition: httpmod.cpp:86
HttpExecutorModule(Bscript::Executor &exec, Clib::Socket &isck)
Definition: httpmod.cpp:39
bool send_nowait(const void *vdata, unsigned datalen, unsigned *nsent)
Definition: wnsckt.cpp:583
std::vector< BObjectRef > fparams
Definition: executor.h:133
void read_query_string(const std::string &query_string)
Definition: httpmod.cpp:166
const String * getStringParam(unsigned param)
Definition: execmodl.cpp:36
void http_writeline(Clib::Socket &sck, const std::string &s)
Definition: polwww.cpp:160
std::string name
Definition: osmod.cpp:943
Bscript::BObjectImp * mf_WriteHtml()
Definition: httpmod.cpp:47
std::string http_decodestr(const std::string &s)
Definition: polwww.cpp:229
#define INFO_PRINT
Definition: logfacility.h:223
const char * data() const
Definition: impstr.h:66
Definition: berror.cpp:12
Module::OSExecutorModule * os_module
Definition: uoexec.h:37
void SleepForMs(int msecs)
Definition: osmod.cpp:834