/////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) // // See accompanying file COPYING.TXT file for licensing details. // /////////////////////////////////////////////////////////////////////////////// #define CPPCMS_SOURCE #include #include "http_protocol.h" #include #include namespace cppcms { namespace http { struct content_type::data { std::string type; std::string subtype; std::string media_type; std::map parameters; }; content_type::content_type() { } content_type::content_type(content_type const &other) : d(other.d) { } content_type::~content_type() { } content_type const &content_type::operator=(content_type const &other) { d=other.d; return *this; } std::string content_type::type() const { if(d) return d->type; return std::string(); } std::string content_type::subtype() const { if(d) return d->subtype; return std::string(); } std::string content_type::media_type() const { if(d) return d->media_type; return std::string(); } bool content_type::is_form_urlencoded() const { if(d) return d->media_type == "application/x-www-form-urlencoded"; return false; } bool content_type::is_multipart_form_data() const { if(d) return d->media_type == "multipart/form-data"; return false; } std::string content_type::charset() const { return parameter_by_key("charset"); } std::map content_type::parameters() const { if(d) { return d->parameters; } return std::map(); } bool content_type::parameter_is_set(std::string const &key) const { if(!d) return false; if(d->parameters.find(key)==d->parameters.end()) return false; return true; } std::string content_type::parameter_by_key(std::string const &key) const { if(!d) return std::string(); std::map::const_iterator p; p = d->parameters.find(key); if( p == d->parameters.end()) return std::string(); return p->second; } void content_type::parse(char const *begin,char const *end) { begin = protocol::skip_ws(begin,end); if(begin == end) return; char const *type_end = protocol::tocken(begin,end); if(type_end == begin) return; std::string type(begin,type_end); begin = type_end; if(begin == end || *begin++ != '/') return; type_end = protocol::tocken(begin,end); if(type_end == begin) return; std::string subtype(begin,type_end); begin = type_end; std::transform(type.begin(),type.end(),type.begin(),protocol::ascii_to_lower); std::transform(subtype.begin(),subtype.end(),subtype.begin(),protocol::ascii_to_lower); d->type = type; d->subtype = subtype; d->media_type = type + "/" + subtype; while(begin!=end) { begin = protocol::skip_ws(begin,end); if(begin == end || *begin++ != ';' || (begin=protocol::skip_ws(begin,end))==end) return; char const *param_end = protocol::tocken(begin,end); if(param_end == begin) return; std::string param(begin,param_end); std::transform(param.begin(),param.end(),param.begin(),protocol::ascii_to_lower); begin = protocol::skip_ws(param_end,end); if(begin==end || *begin++!='=') return; begin = protocol::skip_ws(begin,end); if(begin==end) return; std::string value; if(*begin == '"') { char const *tmp = begin; value = protocol::unquote(tmp,end); if(tmp == begin) return; begin = tmp; } else { char const *tmp = protocol::tocken(begin,end); if(tmp == begin) return; value.assign(begin,tmp); begin = tmp; } d->parameters.insert(std::make_pair(param,value)); } } content_type::content_type(char const *begin,char const *end) : d(new content_type::data()) { parse(begin,end); } content_type::content_type(char const *s) : d(new content_type::data()) { char const *begin = s; char const *end = s + strlen(s); parse(begin,end); } content_type::content_type(std::string const &ct) : d(new content_type::data()) { char const *begin = ct.c_str(); char const *end = begin + ct.size(); parse(begin,end); } } // http } // cppcms