wibble  1.1
http.h
Go to the documentation of this file.
1 #ifndef WIBBLE_NET_HTTP_H
2 #define WIBBLE_NET_HTTP_H
3 
4 /*
5  * net/http - HTTP server utilities
6  *
7  * Copyright (C) 2010 Enrico Zini <enrico@enricozini.org>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23 
24 #include <string>
25 #include <map>
26 #include <wibble/regexp.h>
27 #include <wibble/net/mime.h>
28 #include <iosfwd>
29 #include <stdexcept>
30 
31 namespace wibble {
32 namespace net {
33 namespace http {
34 
35 struct Request;
36 
37 struct error : public std::exception
38 {
39  int code;
40  std::string desc;
41  std::string msg;
42 
43  error(int code, const std::string& desc)
44  : code(code), desc(desc) {}
45  error(int code, const std::string& desc, const std::string& msg)
46  : code(code), desc(desc), msg(msg) {}
47  virtual ~error() throw () {}
48 
49  virtual const char* what() const throw ();
50 
51  virtual void send(Request& req);
52 };
53 
54 struct error400 : public error
55 {
56  error400() : error(400, "Bad request") {}
57  error400(const std::string& msg) : error(400, "Bad request", msg) {}
58 };
59 
60 struct error404 : public error
61 {
62  error404() : error(404, "Not found") {}
63  error404(const std::string& msg) : error(404, "Not found", msg) {}
64 
65  virtual void send(Request& req);
66 };
67 
68 struct Request
69 {
70  // Request does not take ownership of the socket: it is up to the caller to
71  // close it
72  int sock;
73  std::string peer_hostname;
74  std::string peer_hostaddr;
75  std::string peer_port;
76  std::string server_name;
77  std::string server_port;
78  std::string script_name;
79  std::string path_info;
80  std::string query_string;
82  std::string server_software;
85 
86  std::string method;
87  std::string url;
88  std::string version;
89  std::map<std::string, std::string> headers;
91 
93 
94  std::map<std::string, std::string> extra_response_headers;
95 
96  Request();
97 
112  bool read_request();
113 
120  bool read_buf(std::string& res, size_t size);
121 
122  // Read HTTP method and its following empty line
123  bool read_method();
124 
131  bool read_headers();
132 
137  void set_cgi_env();
138 
140  void send(const std::string& buf);
141 
143  void send_status_line(int code, const std::string& msg, const std::string& version = "HTTP/1.0");
144 
146  void send_server_header();
147 
149  void send_date_header();
150 
152  void send_extra_response_headers();
153 
155  void send_result(const std::string& content, const std::string& content_type="text/html; charset=utf-8", const std::string& filename=std::string());
156 
158  void discard_input();
159 
166  std::string pop_path_info();
167 
173  std::string path_info_head();
174 };
175 
177 struct Param
178 {
179  virtual ~Param();
180 
187  virtual void parse(const std::string& str) = 0;
188 };
189 
191 struct ParamSingle : public std::string, public Param
192 {
193  virtual void parse(const std::string& str);
194 };
195 
197 struct ParamMulti : public std::vector<std::string>, public Param
198 {
199  virtual void parse(const std::string& str);
200 };
201 
205 struct FileParam
206 {
208  struct FileInfo
209  {
211  std::string fname;
213  std::string client_fname;
214 
218  bool read(net::mime::Reader& mime_reader,
219  std::map<std::string, std::string> headers,
220  const std::string& outdir,
221  const std::string& fname_blacklist,
222  const std::string& client_fname,
223  int sock,
224  const std::string& boundary,
225  size_t inputsize);
226  };
227 
228  virtual ~FileParam();
229 
233  virtual bool read(
234  net::mime::Reader& mime_reader,
235  std::map<std::string, std::string> headers,
236  const std::string& outdir,
237  const std::string& fname_blacklist,
238  const std::string& client_fname,
239  int sock,
240  const std::string& boundary,
241  size_t inputsize) = 0;
242 };
243 
247 struct FileParamSingle : public FileParam
248 {
249  FileInfo info;
250 
255  FileParamSingle(const std::string& fname=std::string());
256 
257  virtual bool read(
258  net::mime::Reader& mime_reader,
259  std::map<std::string, std::string> headers,
260  const std::string& outdir,
261  const std::string& fname_blacklist,
262  const std::string& client_fname,
263  int sock,
264  const std::string& boundary,
265  size_t inputsize);
266 };
267 
271 struct FileParamMulti : public FileParam
272 {
273  std::vector<FileInfo> files;
274 
275  virtual bool read(
276  net::mime::Reader& mime_reader,
277  std::map<std::string, std::string> headers,
278  const std::string& outdir,
279  const std::string& fname_blacklist,
280  const std::string& client_fname,
281  int sock,
282  const std::string& boundary,
283  size_t inputsize);
284 };
285 
292 struct Params : public std::map<std::string, Param*>
293 {
295  std::map<std::string, FileParam*> files;
296 
299 
302 
311 
320 
326  std::string conf_outdir;
327 
335  std::string conf_fname_blacklist;
336 
337 
338  Params();
339  ~Params();
340 
342  template<typename TYPE>
343  TYPE* add(const std::string& name)
344  {
345  TYPE* res = new TYPE;
346  add(name, res);
347  return res;
348  }
349 
351  void add(const std::string& name, Param* param);
352 
354  void add(const std::string& name, FileParam* param);
355 
361  Param* obtain_field(const std::string& name);
362 
368  FileParam* obtain_file_field(const std::string& name);
369 
371  Param* field(const std::string& name);
372 
374  FileParam* file_field(const std::string& name);
375 
377  void parse_get_or_post(net::http::Request& req);
378 
380  void parse_urlencoded(const std::string& qstring);
381 
383  void parse_multipart(net::http::Request& req, size_t inputsize, const std::string& content_type);
384 
386  void parse_post(net::http::Request& req);
387 };
388 
389 
390 }
391 }
392 }
393 
394 // vim:set ts=4 sw=4:
395 #endif
wibble::net::http::FileParamSingle
Single file upload field.
Definition: http.h:247
wibble::iterator
Iterator< typename I::value_type > iterator(I i)
Definition: iterator.h:123
wibble::net::mime::Reader::read_until_boundary
bool read_until_boundary(int sock, const std::string &boundary, std::ostream &out, size_t max=0)
Read until boundary is found, sending data to the given ostream.
Definition: mime.cpp:159
wibble::net::http::FileParam
File upload parameter.
Definition: http.h:205
wibble::net::http::Request::space_splitter
wibble::Splitter space_splitter
Definition: http.h:90
regexp.h
wibble::str::Split::end
const_iterator end() const
Definition: string.h:402
wibble::str::joinpath
std::string joinpath(const std::string &path1, const std::string &path2)
Join two paths, adding slashes when appropriate.
Definition: string.h:257
wibble::net::http::error::what
virtual const char * what() const
Definition: http.cpp:38
wibble::net::http::Request::read_buf
bool read_buf(std::string &res, size_t size)
Read a fixed amount of data from the file descriptor.
Definition: http.cpp:159
wibble::net::http::Params::file_field
FileParam * file_field(const std::string &name)
Get a file field by name.
Definition: http.cpp:564
wibble::net::http::Params::obtain_file_field
FileParam * obtain_file_field(const std::string &name)
Get a normal fileld during form parsing.
Definition: http.cpp:544
wibble::net::http::error404::error404
error404()
Definition: http.h:62
wibble::str::Split::const_iterator
Definition: string.h:321
wibble::net::http::Params::field
Param * field(const std::string &name)
Get a field by name.
Definition: http.cpp:556
wibble::str::Split::begin
const_iterator begin() const
Split the string and iterate the resulting tokens.
Definition: string.h:401
wibble::net::mime::Reader::read_headers
bool read_headers(int sock, std::map< std::string, std::string > &headers)
Read MIME headers.
Definition: mime.cpp:68
string.h
wibble::net::http::error::code
int code
Definition: http.h:39
wibble::str::toupper
std::string toupper(const std::string &str)
Convert a string to uppercase.
Definition: string.h:228
wibble::Regexp::match
bool match(const std::string &str, int flags=0)
Definition: regexp.cpp:74
wibble::net::http::Request::server_name
std::string server_name
Definition: http.h:76
wibble::stream::PosixBuf
Definition: posix.h:15
wibble::net::http::Request::read_request
bool read_request()
Read request method and headers from sock.
Definition: http.cpp:83
wibble::net::http::Request::path_info_head
std::string path_info_head()
Return the first component from path_info.
Definition: http.cpp:116
wibble::net::http::Params::Params
Params()
Definition: http.cpp:495
wibble::net::http::Request::method
std::string method
Definition: http.h:86
wibble::net::http::Params::conf_max_input_size
size_t conf_max_input_size
Maximum size of POST input data.
Definition: http.h:298
wibble::net::http::Params::conf_max_field_size
size_t conf_max_field_size
Maximum size of field data for one non-file field.
Definition: http.h:301
wibble::net::http::error404
Definition: http.h:60
wibble::net::http::Request::set_cgi_env
void set_cgi_env()
Set the CGI environment variables for the current process using this request.
Definition: http.cpp:224
wibble::net::http::Request::peer_port
std::string peer_port
Definition: http.h:75
wibble::net::http::error::desc
std::string desc
Definition: http.h:40
wibble::net::http::Params::conf_accept_unknown_fields
bool conf_accept_unknown_fields
Whether to accept unknown fields.
Definition: http.h:310
wibble::net::http::FileParam::FileInfo::read
bool read(net::mime::Reader &mime_reader, std::map< std::string, std::string > headers, const std::string &outdir, const std::string &fname_blacklist, const std::string &client_fname, int sock, const std::string &boundary, size_t inputsize)
Handle a file upload from a multipart/form-data file upload part.
Definition: http.cpp:406
wibble::net::http::Request::version
std::string version
Definition: http.h:88
wibble::net::http::Params::~Params
~Params()
Definition: http.cpp:503
wibble::net::http::Request::send
void send(const std::string &buf)
Send the content of buf, verbatim, to the client.
Definition: http.cpp:295
wibble::net::http::error::error
error(int code, const std::string &desc, const std::string &msg)
Definition: http.h:45
wibble::net::http::Params::add
TYPE * add(const std::string &name)
Universal, automatic add method.
Definition: http.h:343
wibble::net::http::error400
Definition: http.h:54
wibble::net::http::error400::error400
error400(const std::string &msg)
Definition: http.h:57
wibble::net::http::FileParamMulti
Multiple file uploads with the same name.
Definition: http.h:271
wibble::str::urldecode
std::string urldecode(const std::string &str)
Decode an urlencoded string.
Definition: string.cpp:178
wibble::net::http::FileParam::FileInfo::fname
std::string fname
File pathname on the local file system.
Definition: http.h:211
wibble::net::http::FileParamSingle::read
virtual bool read(net::mime::Reader &mime_reader, std::map< std::string, std::string > headers, const std::string &outdir, const std::string &fname_blacklist, const std::string &client_fname, int sock, const std::string &boundary, size_t inputsize)
Handle a file upload from a multipart/form-data file upload part.
Definition: http.cpp:468
wibble::net::http::Request::url
std::string url
Definition: http.h:87
wibble::net::http::Request::sock
int sock
Definition: http.h:72
wibble::net::http::FileParamMulti::read
virtual bool read(net::mime::Reader &mime_reader, std::map< std::string, std::string > headers, const std::string &outdir, const std::string &fname_blacklist, const std::string &client_fname, int sock, const std::string &boundary, size_t inputsize)
Handle a file upload from a multipart/form-data file upload part.
Definition: http.cpp:481
wibble::net::http::Request::response_started
bool response_started
true if some response has already been sent to the client
Definition: http.h:84
wibble::net::http::Request::server_port
std::string server_port
Definition: http.h:77
wibble::net::http::Params::conf_outdir
std::string conf_outdir
Directory where we write uploaded files.
Definition: http.h:326
wibble::str::basename
std::string basename(const std::string &pathname)
Given a pathname, return the file name without its path.
Definition: string.h:124
wibble::net::http::error400::error400
error400()
Definition: http.h:56
wibble::list::end
ListIterator< List > end(List)
Definition: list.h:425
wibble::net::http::Params::files
std::map< std::string, FileParam * > files
File parameters.
Definition: http.h:295
wibble::net::mime::Reader
Definition: mime.h:33
wibble::net::http::Request::script_name
std::string script_name
Definition: http.h:78
wibble::list::map
Map< List, F > map(const List &l, const F &f)
Definition: list.h:381
wibble::net::http::Request::peer_hostname
std::string peer_hostname
Definition: http.h:73
wibble::net::http::Param::parse
virtual void parse(const std::string &str)=0
Parse the value of this parameter from the given unescaped string value.
wibble::net::http::Request::send_server_header
void send_server_header()
Send the HTTP server header.
Definition: http.cpp:315
wibble::net::http::Param
Base interface for GET or POST parameters.
Definition: http.h:177
wibble::net::http::Request::extra_response_headers
std::map< std::string, std::string > extra_response_headers
Definition: http.h:94
wibble::net::http::Request::mime_reader
wibble::net::mime::Reader mime_reader
Definition: http.h:92
wibble::net::http::Request
Definition: http.h:68
wibble::net::http::Request::query_string
std::string query_string
Definition: http.h:80
wibble::net::mime::Reader::read_line
bool read_line(int sock, std::string &res)
Read a line from the file descriptor.
Definition: mime.cpp:37
wibble::net::http::Params
Parse and store HTTP query parameters.
Definition: http.h:292
wibble::net::http::Request::path_info
std::string path_info
Definition: http.h:79
wibble::net::http::Request::send_status_line
void send_status_line(int code, const std::string &msg, const std::string &version="HTTP/1.0")
Send the HTTP status line.
Definition: http.cpp:307
wibble::net::http::error::msg
std::string msg
Definition: http.h:41
wibble::net::http::error::error
error(int code, const std::string &desc)
Definition: http.h:43
wibble::exception::System
Base class for system exceptions.
Definition: exception.h:396
wibble::net::http::Request::send_extra_response_headers
void send_extra_response_headers()
Send headers in extra_response_headers.
Definition: http.cpp:341
wibble::net::http::Params::parse_post
void parse_post(net::http::Request &req)
Parse parameters from HTTP POST input.
Definition: http.cpp:687
wibble::net::http::FileParamMulti::files
std::vector< FileInfo > files
Definition: http.h:273
wibble::net::http::FileParamSingle::FileParamSingle
FileParamSingle(const std::string &fname=std::string())
If a file name is given, use its base name for storing the file; else, use the file name given by the...
Definition: http.cpp:463
wibble::net::http::Request::pop_path_info
std::string pop_path_info()
Remove the first component from path_info, append it to script_name and return it.
Definition: http.cpp:131
wibble::Splitter::end
const_iterator end()
Definition: regexp.h:201
wibble::net::http::Params::conf_accept_unknown_file_fields
bool conf_accept_unknown_file_fields
Whether to accept unknown file upload fields.
Definition: http.h:319
wibble::Splitter::const_iterator
Warning: the various iterators reuse the Regexps and therefore only one iteration of a Splitter can b...
Definition: regexp.h:155
wibble::net::http::Request::read_headers
bool read_headers()
Read HTTP headers.
Definition: http.cpp:217
wibble::net::http::FileParamSingle::info
FileInfo info
Definition: http.h:249
wibble::str::Split
Split a string where a given substring is found.
Definition: string.h:314
wibble::list::begin
ListIterator< List > begin(List l)
Definition: list.h:420
wibble::net::http::error404::error404
error404(const std::string &msg)
Definition: http.h:63
wibble::net::http::error
Definition: http.h:37
wibble::net::http::FileParam::FileInfo
Infomation about one uploaded file.
Definition: http.h:208
wibble::sys::fs::size
size_t size(const std::string &file)
File size.
Definition: fs.cpp:287
wibble::net::http::ParamMulti::parse
virtual void parse(const std::string &str)
Parse the value of this parameter from the given unescaped string value.
Definition: http.cpp:399
wibble::net::http::Params::parse_urlencoded
void parse_urlencoded(const std::string &qstring)
Parse parameters from urlencoded form data.
Definition: http.cpp:586
wibble
Definition: amorph.h:17
wibble::ERegexp
Definition: regexp.h:82
wibble::Splitter::begin
const_iterator begin(const std::string &str)
Split the string and iterate the resulting tokens.
Definition: regexp.h:200
wibble::Splitter
Split a string using a regular expression to match the token separators.
Definition: regexp.h:145
mime.h
exception.h
wibble::net::mime::Reader::discard_until_boundary
bool discard_until_boundary(int sock, const std::string &boundary)
Read until boundary is found, sending data to the given ostream.
Definition: mime.cpp:192
wibble::net::http::Request::server_software
std::string server_software
String to use as server software "NAME/version".
Definition: http.h:82
wibble::net::http::error::send
virtual void send(Request &req)
Definition: http.cpp:44
wibble::net::http::Params::parse_multipart
void parse_multipart(net::http::Request &req, size_t inputsize, const std::string &content_type)
Parse parameters from multipart/form-data.
Definition: http.cpp:614
wibble::net::http::Params::obtain_field
Param * obtain_field(const std::string &name)
Get a normal fileld during form parsing.
Definition: http.cpp:533
wibble::str::fmtf
std::string fmtf(const char *f,...)
Definition: string.cpp:113
wibble::net::http::Request::peer_hostaddr
std::string peer_hostaddr
Definition: http.h:74
posix.h
wibble::net::http::error::~error
virtual ~error()
Definition: http.h:47
wibble::net::http::FileParam::FileInfo::client_fname
std::string client_fname
File pathname provided by the client.
Definition: http.h:213
wibble::net::http::ParamSingle::parse
virtual void parse(const std::string &str)
Parse the value of this parameter from the given unescaped string value.
Definition: http.cpp:394
wibble::net::http::Params::conf_fname_blacklist
std::string conf_fname_blacklist
String containing blacklist characters that are replaced with "_" in the file name.
Definition: http.h:335
wibble::net::http::Request::headers
std::map< std::string, std::string > headers
Definition: http.h:89
wibble::net::http::ParamMulti
Multi-valued parameter.
Definition: http.h:197
wibble::net::http::Params::parse_get_or_post
void parse_get_or_post(net::http::Request &req)
Parse parameters as GET or POST according to request method.
Definition: http.cpp:572
wibble::net::http::Param::~Param
virtual ~Param()
Definition: http.cpp:392
http.h
wibble::net::http::Request::send_date_header
void send_date_header()
Send the HTTP date header.
Definition: http.cpp:322
wibble::net::http::FileParam::read
virtual bool read(net::mime::Reader &mime_reader, std::map< std::string, std::string > headers, const std::string &outdir, const std::string &fname_blacklist, const std::string &client_fname, int sock, const std::string &boundary, size_t inputsize)=0
Handle a file upload from a multipart/form-data file upload part.
wibble::net::http::Request::read_method
bool read_method()
Definition: http.cpp:183
wibble::net::http::Request::discard_input
void discard_input()
Discard all input from the socket.
Definition: http.cpp:375
wibble::exception::Consistency
Exception thrown when some consistency check fails.
Definition: exception.h:254
wibble::net::http::ParamSingle
Single-valued parameter.
Definition: http.h:191
wibble::net::http::Request::send_result
void send_result(const std::string &content, const std::string &content_type="text/html; charset=utf-8", const std::string &filename=std::string())
Send a string as result.
Definition: http.cpp:361
wibble::net::http::FileParam::~FileParam
virtual ~FileParam()
Definition: http.cpp:404
wibble::grcal::date::now
void now(int *dst)
Fill in an int[6] with the UTC values for now.
wibble::exception::File
Base class for exceptions for file I/O.
Definition: exception.h:420