Skip to content

Commit

Permalink
Implemented a sender and a receiver to make it easy to send and recei…
Browse files Browse the repository at this point in the history
…ve data.

Implemented custom exceptions as: curl_easy_exception, curl_multi_exception, curl_share_exception.
Removed curl_error.h file: Now you have: curl_exception.h
  • Loading branch information
JosephP91 committed Jun 30, 2014
1 parent 107196f commit 87b9b2c
Show file tree
Hide file tree
Showing 18 changed files with 443 additions and 224 deletions.
66 changes: 59 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ Simple usage example
Here's an example of a simple HTTP request to get google web page, using the curl_easy interface:

`````c++
#include "../include/curl_easy.h"
// only "curl_easy.h" if you use above submodule-way of compilation and linking
#include "curl_easy.h"

using curl::curl_easy;

Expand All @@ -48,7 +47,7 @@ int main(int argc, const char **argv) {
easy.add(curl_pair<CURLoption,long>(CURLOPT_FOLLOWLOCATION,1L));
try {
easy.perform();
} catch (curl_error error) {
} catch (curl_easy_exception error) {
// If you want to get the entire error stack we can do:
vector<pair<string,string>> errors = error.what();
// Otherwise we could print the stack like this:
Expand All @@ -64,7 +63,6 @@ Here's instead, the creation of an HTTPS POST login form:
`````c++
#include "curl_easy.h"
#include "curl_form.h"
// only "curl_easy.h" and "curl_form.h" if you use above submodule-way of compilation and linking
using curl::curl_form;
using curl::curl_easy;
Expand All @@ -89,7 +87,7 @@ int main(int argc, const char * argv[]) {
easy.add(curl_pair<CURLoption,bool>(CURLOPT_SSL_VERIFYPEER,false));
easy.add(curl_pair<CURLoption,curl_form>(CURLOPT_HTTPPOST,form));
easy.perform();
} catch (curl_error error) {
} catch (curl_easy_exception error) {
// Print errors, if any
error.print_traceback();
}
Expand Down Expand Up @@ -120,7 +118,7 @@ int main(int argc, const char * argv[]) {
easy.add(curl_pair<CURLoption,long>(CURLOPT_FOLLOWLOCATION,1L));
try {
easy.perform();
} catch (curl_error error) {
} catch (curl_easy_exception error) {
// If you want to get the entire error stack we can do:
vector<pair<string,string>> errors = error.what();
// Otherwise we could print the stack like this:
Expand All @@ -131,4 +129,58 @@ int main(int argc, const char * argv[]) {
}
`````
That's it! :)
I have implemented a sender and a receiver to make it easy to use send/receive without handling
buffers. For example, a very simple send/receiver would be:
`````c++
#include "curl_easy.h"
#include "curl_form.h"
#include "curl_pair.h"
#include "curl_receiver.h"
#include "curl_sender.h"
using curl::curl_form;
using curl::curl_easy;
using curl::curl_sender;
using curl::curl_receiver;
int main() {
// Simple request
string request = "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n";
// Creation of easy object.
curl_easy easy;
try {
easy.add(curl_pair<CURLoption,string>(CURLOPT_URL,"http://example.com"));
// Just connect
easy.add(curl_pair<CURLoption,bool>(CURLOPT_CONNECT_ONLY,true));
easy.perform();
} catch (curl_easy_exception error) {
// If you want to get the entire error stack we can do:
vector<pair<string,string>> errors = error.what();
// Print errors if any
error.print_traceback();
}
// Creation of a sender. You should wait here using select to check if socket is ready to send.
curl_sender<string> sender(easy);
sender.send(request);
cout<<"Sent bytes: "<<sender.get_sent_bytes()<<endl;
for(;;) {
// You should wait here to check if socket is ready to receive
try {
// Create a receiver
curl_receiver<char,1024> receiver;
// Receive the content on the easy handler
receiver.receive(easy);
// Prin
cout<<"Receiver bytes: "<<receiver.get_received_bytes()<<endl;
} catch (curl_easy_exception error) {
// If any errors occurs, exit from the loop
break;
}
}
return 0;
}
`````
30 changes: 5 additions & 25 deletions include/curl_easy.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ using std::ostream;

using curl::curl_pair;
using curl::curl_interface;
using curl::curl_easy_exception;

namespace curl {
/**
Expand Down Expand Up @@ -100,17 +101,7 @@ namespace curl {
* get_info overloaded method. It it used when the second argument is
* of struct_slist * type.
*/
vector<string> get_info(const CURLINFO) const;
/**
* This method wraps the libcurl function that receives raw data from
* the established connection.
*/
bool receive(void *, size_t, size_t *);
/**
* This method wraps the libcurl function that sends arbitrary data
* over the established connection.
*/
void send(const void *, size_t, size_t *);
unique_ptr<vector<string>> get_info(const CURLINFO) const;
/**
* Using this function, you can explicitly mark a running connection
* to get paused, and you can unpause a connection that was previously
Expand Down Expand Up @@ -142,12 +133,6 @@ namespace curl {
* Simple getter method used to return the easy handle.
*/
CURL *get_curl() const;
protected:
/**
* Utility function used to convert libcurl error code into
* error messages.
*/
string to_string(const CURLcode) const noexcept;
private:
CURL *curl;
};
Expand All @@ -156,7 +141,7 @@ namespace curl {
template<typename T> void curl_easy::add(const curl_pair<CURLoption,T> pair) {
const CURLcode code = curl_easy_setopt(this->curl,pair.first(),pair.second());
if (code != CURLE_OK) {
throw curl_error(this->to_string(code),__FUNCTION__);
throw curl_easy_exception(code,__FUNCTION__);
}
}

Expand All @@ -176,11 +161,11 @@ namespace curl {

// Implementation of get_session_info method.
template<typename T> unique_ptr<T> curl_easy::get_info(const CURLINFO info) const {
// Use a unique_ptr to automatic destroy the memory reserved with new.
// Use a unique_ptr to automatic destroy the memory reserved with new when the pointer goes out of scope.
unique_ptr<T> ptr(new T);
const CURLcode code = curl_easy_getinfo(this->curl,info,ptr.get());
if (code != CURLE_OK) {
throw curl_error(this->to_string(code),__FUNCTION__);
throw curl_easy_exception(code,__FUNCTION__);
}
return ptr;
}
Expand All @@ -189,11 +174,6 @@ namespace curl {
inline CURL *curl_easy::get_curl() const {
return this->curl;
}

// Implementation of to_string method.
inline string curl_easy::to_string(const CURLcode code) const noexcept {
return curl_easy_strerror(code);
}
}

#endif /* curl_easy_H */
73 changes: 0 additions & 73 deletions include/curl_error.h

This file was deleted.

125 changes: 125 additions & 0 deletions include/curl_exception.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//
// curl_exception.h
// curlcpp
//
// Created by Giuseppe Persico on 02/06/14.
//

#ifndef __curlcpp__curl_exception__
#define __curlcpp__curl_exception__

#include <iostream>
#include <string>
#include <exception>
#include <utility>
#include <vector>
#include <curl/curl.h>

using std::cout;
using std::endl;
using std::string;
using std::exception;
using std::pair;
using std::vector;

namespace curl {
/**
* This class rapresent a custom exception for libcurl errors.
* If a function throws an error, its name will be added to a
* vector (treated like a stack, because if I had used a stack,
* to print it, I should have to remove all the elements), so
* users can keep track of which method threw which exception.
*/
class curl_exception : public exception {
public:
/**
* This constructor is used to build the error.
*/
curl_exception(const string, const string);
/**
* The destructor, in this case, doesen't do anything.
*/
~curl_exception() throw();
using exception::what;
/**
* Override of exception's what method, used to returns
* the vector of errors.
*/
const vector<pair<string,string>> what();
/**
* Simple method which prints the entire error stack.
*/
void print_traceback() const;
private:
/**
* The error container must be static or will be cleared
* when an exceptions is thrown.
*/
static vector<pair<string,string>> traceback;
};

// Implementation of print_traceback
inline void curl_exception::print_traceback() const {
for_each(curl_exception::traceback.begin(),curl_exception::traceback.end(),[](const pair<string,string> &value) {
cout<<"ERROR: "<<value.first<<" ::::: FUNCTION: "<<value.second<<endl;
});
}

// Implementation of what method.
inline const vector<pair<string,string>> curl_exception::what() {
return curl_exception::traceback;
}

/**
* Derived class used to rapresent a condition of error returned by the easy
* interface functions.
*/
class curl_easy_exception : public curl_exception {
public:
/**
* This constructor allows to specify a custom error message and the method name where
* the exeption has been thrown.
*/
curl_easy_exception(const string error, const string method) : curl_exception(error,method) {}
/**
* The constructor will transfrom a CURLcode error in a proper error message.
*/
curl_easy_exception(const CURLcode code, const string method) : curl_exception(curl_easy_strerror(code),method) {}
};

/**
* Derived class used to rapresent a condition of error returned by the multi
* interface functions.
*/
class curl_multi_exception : public curl_exception {
public:
/**
* This constructor allows to specify a custom error message and the method name where
* the exeption has been thrown.
*/
curl_multi_exception(const string error, const string method) : curl_exception(error,method) {}
/**
* The constructor will transform a CURLMcode error in a proper error message.
*/
curl_multi_exception(const CURLMcode code, const string method) : curl_exception(curl_multi_strerror(code),method) {}
};

/**
* Derived class used to rapresent a condition of error returned by the share
* interface functions.
*/
class curl_share_exception : public curl_exception {
public:
/**
* This constructor allows to specify a custom error message and the method name where
* the exeption has been thrown.
*/
curl_share_exception(const string error, const string method) : curl_exception(error,method) {}
/**
* The constructor will transform a CURLSHcode error in a proper error message.
*/
curl_share_exception(const CURLSHcode code, const string method) : curl_exception(curl_share_strerror(code),method) {}
};
}

#endif /* defined(__curlcpp__curl_exception__) */
4 changes: 2 additions & 2 deletions include/curl_form.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
#include <vector>
#include <string>
#include <new>
#include "curl_error.h"
#include "curl_exception.h"
#include "curl_pair.h"

using std::string;
using std::vector;
using std::bad_alloc;
using curl::curl_pair;
using curl::curl_error;
using curl::curl_exception;

namespace curl {
/**
Expand Down
Loading

0 comments on commit 87b9b2c

Please sign in to comment.