C++ 11 Http请求及CSV读取示例

这是公司的一个测试任务,基本就是要验一下数据库里面的URL是不是都是通的。我想的是先从数据库里面把数据导出来,放到CSV文件里面,然后再逐行校验。

CMakeLists.txt


cmake_minimum_required(VERSION 2.6)
project(chat_room)

add_definitions(-std=c++14)
add_definitions(-g)



find_package(Boost REQUIRED COMPONENTS
    system
    filesystem
    serialization
    program_options
    thread
    )

include_directories(${Boost_INCLUDE_DIRS}  ${CMAKE_CURRENT_SOURCE_DIR}/include)


file( GLOB APP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURRENT_SOURCE_DIR}/include/http/impl/*.cpp)
foreach( sourcefile ${APP_SOURCES} )
        file(RELATIVE_PATH filename ${CMAKE_CURRENT_SOURCE_DIR} ${sourcefile})
    if( "${filename}" STREQUAL "main.cpp")
        string(REPLACE ".cpp" "" file ${filename})
        add_executable(${file}  ${APP_SOURCES})
        target_link_libraries(${file} ${Boost_LIBRARIES})
        target_link_libraries(${file} pthread ssl crypto)
    endif()
endforeach( sourcefile ${APP_SOURCES})

main.cpp

#include "csv/csv_util.h"
#include "http/http_util.h"

#include 

const std::string IMAGE_PATH = "./images";


bool test_a_image(std::string host, std::string path, std::string result_name) {
   
    std::string final_path = "/img/" +  path;

    std::string final_result_name = IMAGE_PATH + "/"+ result_name;

    bool res = HttpUtil::get_file(host, final_path , final_result_name);
    if(!res) {
        std::cerr << "Download [ https://" << host << final_path <<  "] failed" << std::endl;
        return false;
    } else {
        std::cout << "Download [ https://" << host << final_path << "] successful" << std::endl;
        return true;
    }
}


int main(int argc, char* argv[]) {
    std::vector columns {"PRODUCT_KEY", "OLD_VALUE", "NEW_VALUE", "CHANGE_TIME"};

    std::string host = "static-s.aa-cdn.net";

    std::size_t index = 0;
    auto res = CSVUtil::read_csv("./among-gp.csv", "PRODUCT_KEY", "OLD_VALUE", "NEW_VALUE", "CHANGE_TIME");
    for(auto && ele: res) {
        std::cout << "=========================================================" << std::endl;
        std::cout << ele.product_id << "\t" << ele.old_url << "\t" << ele.new_url << "\t" << ele.date << std::endl;
        test_a_image(host, ele.old_url, std::to_string(index) + "_old.png");
        test_a_image(host, ele.new_url, std::to_string(index) + "_new.png");
        ++index;
    }

    return 0;
}

include/http/http_util.h

#ifndef _HTTP_UTIL_H_
#define _HTTP_UTIL_H_

#define CPPHTTPLIB_OPENSSL_SUPPORT

#include "http/httplib.h"
#include 


class HttpUtil {
    public:
        /**
         * HttpUtil get method
         * 
         * @param: url the url to be used to get a web page from remote server
         * @param: path the path to be used to get a web page from remote server
         * @param: result_name the download result file path
         */
        static bool get(std::string url, std::string path, std::string result_name);

         /**
         * HttpUtil get_file method
         * 
         * @param: host the host to be used to get an item from remote server
         * @param: path the path to be used to get an item from remote server
         * @param: result_name the download result file path
         */
        static bool get_file(std::string host, std::string path, std::string result_name);
};
#endif

include/http/impl/http_util.cpp

#include "http/http_util.h"

#include 
#include 


bool HttpUtil::get(std::string url, std::string path, std::string result_name) {

    try {
        httplib::Client cli {url};
        auto res = cli.Get(path.c_str());


        if(res->status != 200) {
            std::cerr << "Get [" << url << path << "] failed" << std::endl;
            std::cerr << "Status code : [" << res->status << "]" << "\n"   << "Result body : [" << res->body << "]" 
            << std::endl; 
            return false;
        }
        std::ofstream os {result_name, std::ios_base::out | std::ios_base::binary};
        os << res->body;
       
    } catch(const std::exception & e) {
        std::cerr << "Exception: " << e.what() << std::endl;
        return false;
    }
    return true;
}

bool HttpUtil::get_file(std::string host, std::string path, std::string result_name) {

    try {

        #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
            auto port = 443;
            httplib::SSLClient cli(host, port);
        #else
            auto port = 80;
            httplib::Client cli(host, port);
        #endif

        cli.set_connection_timeout(2);

        std::ofstream os {result_name};
        auto res = cli.Get(path.c_str(),
              [&](const char *data, size_t data_length) {
                os << std::string(data, data_length);
                return true;
              });

        if(!res || res->status != 200) {
            return false;
        }
       
    } catch(const std::exception & e) {
        std::cerr << "Exception: " << e.what() << std::endl;
        return false;
    }
    return true;
}

include/csv/csv_util.h

#ifndef _CSV_UTIL_H_
#define _CSV_UTIL_H_

#include "csv.h"
#include "csv/entity.h"

#include 

class CSVUtil {
    public:
        template
        static std::vector read_csv(std::string file_path, T ... columns) {
            io::CSVReader<4> in {file_path};
            in.read_header(io::ignore_extra_column, columns...);
            Entity entity;
            std::vector results;
            while (in.read_row(entity.product_id, entity.old_url, entity.new_url, entity.date)){
                results.emplace_back(std::move(entity));
            }
            return std::move(results);
        }
};

#endif

include/csv/entity.h

#ifndef _FREDRIC_ENTITY_H_
#define _FREDRIC_ENTITY_H_
#include 
#include 

struct Entity {
    int64_t product_id;
    std::string old_url;
    std::string new_url;
    std::string date;
};
#endif

其中csv.h和httplib.h是两个三方库。直接到github上面搜索并加入头文件就可以了。
程序输出如下,


image.png

下载的图片文件


image.png

你可能感兴趣的:(C++ 11 Http请求及CSV读取示例)