00001 #ifndef WIBBLE_NET_HTTP_H
00002 #define WIBBLE_NET_HTTP_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00071
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
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
00395 #endif