美文网首页
C++ 11 Http请求及CSV读取示例

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

作者: FredricZhu | 来源:发表于2021-08-05 15:42 被阅读0次

    这是公司的一个测试任务,基本就是要验一下数据库里面的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 <iostream>
    
    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<std::string> 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 <string>
    
    
    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 <iostream>
    #include <fstream>
    
    
    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 <vector>
    
    class CSVUtil {
        public:
            template<typename ... T>
            static std::vector<Entity> 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<Entity> 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 <stddef.h>
    #include <string>
    
    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读取示例

          本文链接:https://www.haomeiwen.com/subject/lobmvltx.html