libcurlをつかう

httpでファイルを取得するサンプルを作るために、cURLをつかってみる。

インストール

  • apt-get install libcurl3

Hello easy

とりあえず、標準出力に出してみる。

static void easy()
{
    CURL* c = curl_easy_init();
    if (c == 0) assert(false);

    if (curl_easy_setopt(c, CURLOPT_URL, "http://www.google.com") != CURLE_OK)
        assert(false);
    
    if (curl_easy_perform(c) != CURLE_OK)
        assert(false);

    curl_easy_cleanup(c);
}

Hello Callback

コールバックで読み出す。

  • Header
// File: CHttpContent.h	- last edit:
// Hideo Kinami    12-Aug-2006

// Copyright(C) 2006 by Hideo Kinami. All rights reserved.

#ifndef __C_HTTP_CONTENT_H
#define __C_HTTP_CONTENT_H

#include 

class CHttpContent
{
public:
    CHttpContent(const char* url);
    ~CHttpContent();

    bool retrive();
    const char* getContent();
private:
    enum { INITIAL_SIZE = 1024 };
    size_t bufflen_;
    char*  buff_;
    int    index_;
    CURL*  curl_;

    size_t write(void* ptr, size_t size);
    bool ensureCapacity(size_t size);

    static size_t
    writefunc(void *ptr, size_t size, size_t nmemb, void *stream);

    // should not implements
    CHttpContent(const CHttpContent& rhs);
    CHttpContent& operator=(const CHttpContent& rhs);
};


#endif /* !__C_HTTP_CONTENT_H */

// LOG
// 12-Aug-2006 kinami Created.
  • Source
// File: CHttpContent.cpp    - last edit:
// Hideo Kinami    12-Aug-2006

// Copyright(C) 2006 by Hideo Kinami. All rights reserved.

#include 
#include 

#include "CHttpContent.h"

CHttpContent::CHttpContent(const char* url) :
    bufflen_(INITIAL_SIZE),
    buff_(0),
    index_(0),
    curl_(0)
{
    buff_ = (char*)::malloc(bufflen_);
    if (buff_ == 0) {
        std::cerr << "malloc" << std::endl;
        return;
    }
    *buff_ = 0;
    curl_ = curl_easy_init();
    if (curl_ == 0) {
        std::cerr << "Erro curl_easy_init" << std::endl;
        return;
    }
    CURLcode ret;
    ret = curl_easy_setopt(curl_, CURLOPT_WRITEDATA, this);
    if (ret != CURLE_OK) {
        std::cerr << "curl_easy_setopt CURLOPT_WRITEDATA" << ret << std::endl;
        curl_easy_cleanup(curl_);    
        curl_ = 0;
        return;
    }

    ret = curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, writefunc);
    if (ret != CURLE_OK) {
        std::cerr <<
            "curl_easy_setopt CURLOPT_WRITEFUNCTION" << ret << std::endl;
        curl_easy_cleanup(curl_);    
        curl_ = 0;
        return;
    }

    ret = curl_easy_setopt(curl_, CURLOPT_URL, url);
    if (ret != CURLE_OK) {
        std::cerr << "curl_easy_setopt CURLOPT_URL (" <write(ptr, size*nmemb);
}


// LOG
// 12-Aug-2006 kinami Created.

Hello Makefile

# File: Makefile    - last edit:
# Hideo Kinami    12-Aug-2006

# Copyright(C) 2006 by Hideo Kinami. All rights reserved.

.PHONY: all test clean

TARGET=hellolibcurl

CURL_CFLAGS=$(shell curl-config --cflags)
CURL_LDFLAGS=$(shell curl-config --libs)
CPPFLAGS=
CXXFLAGS=-g -Wall -Werror
LDFLAGS=-lcppunit -lpthread -ldl

SRC= main.cpp CHttpContent.cpp

BUILD=build
OBJS=$(addprefix $(BUILD)/, $(SRC:.cpp=.o))
DPES=$(addprefix $(BUILD)/, $(SRC:.cpp=.d))

ifneq (,$(TEST_NAME))
TEST_NAME_OPTION=--name $(TEST_NAME)
endif

ifneq (,$(TEST_LOOPS))
TEST_LOOP_OPTION=--loops $(TEST_LOOPS)
endif


all: $(TARGET)

test: $(TARGET)
	./$(TARGET) $(TEST_NAME_OPTION) $(TEST_LOOP_OPTION)

clean:
	rm -rf $(BUILD)
	rm -f $(TARGET)
	find . -name '*~' | grep -v '.svn' | xargs rm -f

$(TARGET): $(OBJS)
	g++ $(LDFLAGS) $(CURL_LDFLAGS) -o $@ $^ 

$(BUILD)/%.o: %.cpp
	@if [ ! -d $(@D) ]; then mkdir -p $(@D); fi
	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CURL_CFLAGS) -o $@ $<

$(BUILD)/%.d: %.cpp
	@if [ ! -d $(@D) ]; then mkdir -p $(@D); fi
	$(CXX) -MM -MT '$(@:.d=.o) $@' -MF $@ $(CPPFLAGS) $(CURL_CFLAGS) $<

ifneq (clean ,$(MAKECMDGOALS))
 -include $(DPES)
endif

# Log
# 12-Aug-2006 kinami Created.