wibble 0.1.28
|
00001 #ifndef WIBBLE_NET_HTTP_H 00002 #define WIBBLE_NET_HTTP_H 00003 00004 /* 00005 * net/http - HTTP server utilities 00006 * 00007 * Copyright (C) 2010 Enrico Zini <enrico@enricozini.org> 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 * This library is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 */ 00023 00024 #include <string> 00025 #include <map> 00026 #include <wibble/regexp.h> 00027 #include <wibble/net/mime.h> 00028 #include <iosfwd> 00029 #include <stdexcept> 00030 00031 namespace wibble { 00032 namespace net { 00033 namespace http { 00034 00035 struct Request; 00036 00037 struct error : public std::exception 00038 { 00039 int code; 00040 std::string desc; 00041 std::string msg; 00042 00043 error(int code, const std::string& desc) 00044 : code(code), desc(desc) {} 00045 error(int code, const std::string& desc, const std::string& msg) 00046 : code(code), desc(desc), msg(msg) {} 00047 virtual ~error() throw () {} 00048 00049 virtual const char* what() const throw (); 00050 00051 virtual void send(Request& req); 00052 }; 00053 00054 struct error400 : public error 00055 { 00056 error400() : error(400, "Bad request") {} 00057 error400(const std::string& msg) : error(400, "Bad request", msg) {} 00058 }; 00059 00060 struct error404 : public error 00061 { 00062 error404() : error(404, "Not found") {} 00063 error404(const std::string& msg) : error(404, "Not found", msg) {} 00064 00065 virtual void send(Request& req); 00066 }; 00067 00068 struct Request 00069 { 00070 // Request does not take ownership of the socket: it is up to the caller to 00071 // close it 00072 int sock; 00073 std::string peer_hostname; 00074 std::string peer_hostaddr; 00075 std::string peer_port; 00076 std::string server_name; 00077 std::string server_port; 00078 std::string script_name; 00079 std::string path_info; 00080 std::string query_string; 00082 std::string server_software; 00084 bool response_started; 00085 00086 std::string method; 00087 std::string url; 00088 std::string version; 00089 std::map<std::string, std::string> headers; 00090 wibble::Splitter space_splitter; 00091 00092 wibble::net::mime::Reader mime_reader; 00093 00094 std::map<std::string, std::string> extra_response_headers; 00095 00096 Request(); 00097 00112 bool read_request(); 00113 00120 bool read_buf(std::string& res, size_t size); 00121 00122 // Read HTTP method and its following empty line 00123 bool read_method(); 00124 00131 bool read_headers(); 00132 00137 void set_cgi_env(); 00138 00140 void send(const std::string& buf); 00141 00143 void send_status_line(int code, const std::string& msg, const std::string& version = "HTTP/1.0"); 00144 00146 void send_server_header(); 00147 00149 void send_date_header(); 00150 00152 void send_extra_response_headers(); 00153 00155 void send_result(const std::string& content, const std::string& content_type="text/html; charset=utf-8", const std::string& filename=std::string()); 00156 00158 void discard_input(); 00159 00166 std::string pop_path_info(); 00167 00173 std::string path_info_head(); 00174 }; 00175 00177 struct Param 00178 { 00179 virtual ~Param(); 00180 00187 virtual void parse(const std::string& str) = 0; 00188 }; 00189 00191 struct ParamSingle : public std::string, public Param 00192 { 00193 virtual void parse(const std::string& str); 00194 }; 00195 00197 struct ParamMulti : public std::vector<std::string>, public Param 00198 { 00199 virtual void parse(const std::string& str); 00200 }; 00201 00205 struct FileParam 00206 { 00208 struct FileInfo 00209 { 00211 std::string fname; 00213 std::string client_fname; 00214 00218 bool read(net::mime::Reader& mime_reader, 00219 std::map<std::string, std::string> headers, 00220 const std::string& outdir, 00221 const std::string& fname_blacklist, 00222 const std::string& client_fname, 00223 int sock, 00224 const std::string& boundary, 00225 size_t inputsize); 00226 }; 00227 00228 virtual ~FileParam(); 00229 00233 virtual bool read( 00234 net::mime::Reader& mime_reader, 00235 std::map<std::string, std::string> headers, 00236 const std::string& outdir, 00237 const std::string& fname_blacklist, 00238 const std::string& client_fname, 00239 int sock, 00240 const std::string& boundary, 00241 size_t inputsize) = 0; 00242 }; 00243 00247 struct FileParamSingle : public FileParam 00248 { 00249 FileInfo info; 00250 00255 FileParamSingle(const std::string& fname=std::string()); 00256 00257 virtual bool read( 00258 net::mime::Reader& mime_reader, 00259 std::map<std::string, std::string> headers, 00260 const std::string& outdir, 00261 const std::string& fname_blacklist, 00262 const std::string& client_fname, 00263 int sock, 00264 const std::string& boundary, 00265 size_t inputsize); 00266 }; 00267 00271 struct FileParamMulti : public FileParam 00272 { 00273 std::vector<FileInfo> files; 00274 00275 virtual bool read( 00276 net::mime::Reader& mime_reader, 00277 std::map<std::string, std::string> headers, 00278 const std::string& outdir, 00279 const std::string& fname_blacklist, 00280 const std::string& client_fname, 00281 int sock, 00282 const std::string& boundary, 00283 size_t inputsize); 00284 }; 00285 00292 struct Params : public std::map<std::string, Param*> 00293 { 00295 std::map<std::string, FileParam*> files; 00296 00298 size_t conf_max_input_size; 00299 00301 size_t conf_max_field_size; 00302 00310 bool conf_accept_unknown_fields; 00311 00319 bool conf_accept_unknown_file_fields; 00320 00326 std::string conf_outdir; 00327 00335 std::string conf_fname_blacklist; 00336 00337 00338 Params(); 00339 ~Params(); 00340 00342 template<typename TYPE> 00343 TYPE* add(const std::string& name) 00344 { 00345 TYPE* res = new TYPE; 00346 add(name, res); 00347 return res; 00348 } 00349 00351 void add(const std::string& name, Param* param); 00352 00354 void add(const std::string& name, FileParam* param); 00355 00361 Param* obtain_field(const std::string& name); 00362 00368 FileParam* obtain_file_field(const std::string& name); 00369 00371 Param* field(const std::string& name); 00372 00374 FileParam* file_field(const std::string& name); 00375 00377 void parse_get_or_post(net::http::Request& req); 00378 00380 void parse_urlencoded(const std::string& qstring); 00381 00383 void parse_multipart(net::http::Request& req, size_t inputsize, const std::string& content_type); 00384 00386 void parse_post(net::http::Request& req); 00387 }; 00388 00389 00390 } 00391 } 00392 } 00393 00394 // vim:set ts=4 sw=4: 00395 #endif