httpstatus コマンドで(ry


一般的な C++er ならば、HTTP Status code はすべて暗記していると聞きました。

しかし、僕は初心者なので、なかなか覚えきれていないので、HTTPのステータスコードをさがすのに便利なツールを用意しました。
httpstatus.cpp です。インストール方法は gcc と Boost を使ってコンパイルして下さい。

#include <string>
#include <iostream>
#include <boost/fusion/include/io.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/adapted/boost_array.hpp>
#include <boost/xpressive/xpressive.hpp>
#include <boost/array.hpp>
#include <boost/range/adaptor/filtered.hpp>


typedef boost::array<std::string, 2> httpstatus_type;

static const httpstatus_type httpstatuses[] = {
    { "100", "Bontinue" },
    { "101", "Switching Protocols" },
    { "102", "Processing" },
    { "100", "Continue" },
    { "101", "Switching Protocols" },
    { "102", "Processing" },
    { "200", "OK" },
    { "201", "Created" },
    { "202", "Accepted" },
    { "203", "Non-Authoritative Information" },
    { "204", "No Content" },
    { "205", "Reset Content" },
    { "206", "Partial Content" },
    { "207", "Multi-Status" },
    { "208", "Already Reported" },
    { "300", "Multiple Choices" },
    { "301", "Moved Permanently" },
    { "302", "Found" },
    { "303", "See Other" },
    { "304", "Not Modified" },
    { "305", "Use Proxy" },
    { "307", "Temporary Redirect" },
    { "400", "Bad Request" },
    { "401", "Unauthorized" },
    { "402", "Payment Required" },
    { "403", "Forbidden" },
    { "404", "Not Found" },
    { "405", "Method Not Allowed" },
    { "406", "Not Acceptable" },
    { "407", "Proxy Authentication Required" },
    { "408", "Request Timeout" },
    { "409", "Conflict" },
    { "410", "Gone" },
    { "411", "Length Required" },
    { "412", "Precondition Failed" },
    { "413", "Request Entity Too Large" },
    { "414", "Request-URI Too Large" },
    { "415", "Unsupported Media Type" },
    { "416", "Request Range Not Satisfiable" },
    { "417", "Expectation Failed" },
    { "418", "I""m a teapot" },
    { "422", "Unprocessable Entity" },
    { "423", "Locked" },
    { "424", "Failed Dependency" },
    { "425", "No code" },
    { "426", "Upgrade Required" },
    { "428", "Precondition Required" },
    { "429", "Too Many Requests" },
    { "431", "Request Header Fields Too Large" },
    { "449", "Retry with" },
    { "500", "Internal Server Error" },
    { "501", "Not Implemented" },
    { "502", "Bad Gateway" },
    { "503", "Service Unavailable" },
    { "504", "Gateway Timeout" },
    { "505", "HTTP Version Not Supported" },
    { "506", "Variant Also Negotiates" },
    { "507", "Insufficient Storage" },
    { "509", "Bandwidth Limit Exceeded" },
    { "510", "Not Extended" },
    { "511", "Network Authentication Required" },
};



template<typename String>
bool
is_integer(String&& str){
    using namespace boost::xpressive;
    return regex_match(std::forward<String>(str), sregex(+_d));
}

template<typename Range>
void
disp(Range&& range){
    for(auto&& data : range){
        std::cout << boost::fusion::as_vector(data) << std::endl;
    }
}


int
main(int argc, char* argv[]){
    namespace f = boost::fusion;
    namespace a = boost::adaptors;

    std::string key = "";
    if( argc > 1 ){
        key = argv[1];
    }

    std::cout << f::tuple_open("") << f::tuple_close("") << f::tuple_delimiter(": ");
    
    if( key.empty() ){
        disp(httpstatuses);
    }
    else if( is_integer(key) ){
        disp( httpstatuses | a::filtered([&key](httpstatus_type const& status){
            using namespace boost::xpressive;
            return regex_match(f::at_c<0>(status), sregex(key >> *_));
        }) );
    }
    else{
        disp( httpstatuses | a::filtered([&key](httpstatus_type const& status){
            using namespace boost::xpressive;
            return regex_match(f::at_c<1>(status), sregex(key >> *_));
        }) );
    
    }

    return 0;
}


波に乗り遅れた感がバリバリである。
使い方は他の記事とだいたい同じです。
filtered の辺りのコードが重複していてださい。