curlite.cpp
Go to the documentation of this file.
1 /*
2  * curlite.cpp
3  *
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2013-2014 Ivan Grynko
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  *
26  */
27 
28 //#include "curlite.hpp"
30 
31 // anonymous namespace for internal usage
32 namespace
33 {
34  struct CurlGlobalInitializer
35  {
36  CurlGlobalInitializer() { curlite::global_init(); }
37  ~CurlGlobalInitializer() { curlite::global_cleanup(); }
38  };
39 
40 #ifndef CURLITE_NO_AUTOMATIC_GLOBAL_INITIALIZATION
41  CurlGlobalInitializer globalInitializer;
42 #endif
43 
44 } // end of anonymous namespace
45 
46 
47 namespace curlite
48 {
49  template <class HandlerType>
50  struct Event
51  {
52  HandlerType handler;
53  void *data;
54 
55  Event() : data( nullptr ) { }
56  };
57 
58  struct Easy::Pimpl
59  {
60  CURL *curl;
61  CURLcode err;
62  void *userData;
64 
80 
81  Pimpl();
82 
83  // static cURL callbacks
84  static size_t read( char *data, size_t size, size_t n, void *userPtr );
85  static size_t write( char *data, size_t size, size_t n, void *userPtr );
86  static size_t header( char *data, size_t size, size_t n, void *userPtr );
87  static int seek( void *userPtr, curl_off_t offset, int origin );
88  static int fnMatch( void *userPtr, const char *pattern, const char *string );
89  static curlioerr ioctl( CURL *handle, int cmd, void *userPtr );
90 
91  static int progress( void *userPtr, double dTotal, double dCurrent, double uTotal, double uCurrent );
92  static int xferInfo( void *userPtr, curl_off_t dTotal, curl_off_t dCurrent, curl_off_t uTotal, curl_off_t uCurrent );
93 
94  static long chunkBegin( const void *transferInfo, void *userPtr, int remains );
95  static long chunkEnd( void *userPtr );
96 
97  static curl_socket_t openSocket( void *userPtr, curlsocktype purpose, curl_sockaddr *address );
98  static int closeSocket( void *userPtr, curl_socket_t socket );
99  static int sockOpt( void *userPtr, curl_socket_t socket, curlsocktype purpose );
100 
101  static CURLcode sslContext( CURL *curl, void *sslCtx, void *userPtr );
102  static int debug( CURL *, curl_infotype type, char *data, size_t size, void *userPtr );
103  };
104 
105  /* Pimpl definitions
106  */
107 
108  Easy::Pimpl::Pimpl()
109  {
110  curl = nullptr;
111  err = CURLE_OK;
112  userData = nullptr;
113  throwExceptions = true;
114  }
115 
116  size_t Easy::Pimpl::read( char *data, size_t size, size_t n, void *userPtr )
117  {
118  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
119  {
120  auto &ev = impl->onRead;
121  if( ev.handler ) {
122  return ev.handler( (char*) data, size, n, ev.data );
123  }
124  }
125 
126  return CURL_READFUNC_ABORT;
127  }
128 
129  size_t Easy::Pimpl::write( char *data, size_t size, size_t n, void *userPtr )
130  {
131  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
132  {
133  auto &ev = impl->onWrite;
134  if( ev.handler ) {
135  return ev.handler( (char*) data, size, n, ev.data );
136  }
137  }
138 
139  return 0;
140  }
141 
142  size_t Easy::Pimpl::header( char *data, size_t size, size_t n, void *userPtr )
143  {
144  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
145  {
146  auto &ev = impl->onHeader;
147  if( ev.handler ) {
148  return ev.handler( (char*) data, size, n, ev.data );
149  }
150  }
151 
152  return 0;
153  }
154 
155  int Easy::Pimpl::fnMatch( void *userPtr, const char *pattern, const char *string )
156  {
157  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
158  {
159  auto &ev = impl->onFnMatch;
160  if( ev.handler ) {
161  return ev.handler( ev.data, pattern, string );
162  }
163  }
164 
165  return CURL_FNMATCHFUNC_FAIL;
166  }
167 
168  int Easy::Pimpl::seek( void *userPtr, curl_off_t offset, int origin )
169  {
170  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
171  {
172  auto &ev = impl->onSeek;
173  if( ev.handler ) {
174  return ev.handler( ev.data, offset, origin );
175  }
176  }
177 
178  return 1;
179  }
180 
181  curlioerr Easy::Pimpl::ioctl( CURL *handle, int cmd, void *userPtr )
182  {
183  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
184  {
185  auto &ev = impl->onIoctl;
186  if( ev.handler ) {
187  return ev.handler( handle, cmd, ev.data );
188  }
189  }
190 
191  return CURLIOE_UNKNOWNCMD;
192  }
193 
194  int Easy::Pimpl::progress( void *userPtr, double dTotal, double dCurrent, double uTotal, double uCurrent )
195  {
196  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
197  {
198  auto &ev = impl->onProgress;
199  if( ev.handler ) {
200  return ev.handler( ev.data, dTotal, dCurrent, uTotal, uCurrent );
201  }
202  }
203 
204  return 1;
205  }
206 
207  int Easy::Pimpl::xferInfo( void *userPtr, curl_off_t dTotal, curl_off_t dCurrent, curl_off_t uTotal, curl_off_t uCurrent )
208  {
209  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
210  {
211  auto &ev = impl->onXferInfo;
212  if( ev.handler ) {
213  return ev.handler( ev.data, dTotal, dCurrent, uTotal, uCurrent );
214  }
215  }
216 
217  return 1;
218  }
219 
220  long Easy::Pimpl::chunkBegin( const void *transferInfo, void *userPtr, int remains )
221  {
222  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
223  {
224  auto &ev = impl->onChunkBegin;
225  if( ev.handler ) {
226  return ev.handler( transferInfo, ev.data, remains );
227  }
228  }
229 
230  return CURL_CHUNK_BGN_FUNC_FAIL;
231  }
232 
233  long Easy::Pimpl::chunkEnd( void *userPtr )
234  {
235  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
236  {
237  auto &ev = impl->onChunkEnd;
238  if( ev.handler ) {
239  return ev.handler( ev.data );
240  }
241  }
242 
243  return CURL_CHUNK_END_FUNC_FAIL;
244  }
245 
246  curl_socket_t Easy::Pimpl::openSocket( void *userPtr, curlsocktype purpose, curl_sockaddr *address )
247  {
248  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
249  {
250  auto &ev = impl->onOpenSocket;
251  if( ev.handler ) {
252  return ev.handler( ev.data, purpose, address );
253  }
254  }
255 
256  return CURL_SOCKET_BAD;
257  }
258 
259  int Easy::Pimpl::closeSocket( void *userPtr, curl_socket_t socket )
260  {
261  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
262  {
263  auto &ev = impl->onCloseSocket;
264  if( ev.handler ) {
265  return ev.handler( ev.data, socket );
266  }
267  }
268 
269  return 1;
270  }
271 
272  int Easy::Pimpl::sockOpt( void *userPtr, curl_socket_t socket, curlsocktype purpose )
273  {
274  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
275  {
276  auto &ev = impl->onSockOpt;
277  if( ev.handler ) {
278  return ev.handler( ev.data, socket, purpose );
279  }
280  }
281 
282  return 1;
283  }
284 
285  CURLcode Easy::Pimpl::sslContext( CURL *curl, void *sslCtx, void *userPtr )
286  {
287  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
288  {
289  auto &ev = impl->onSslContext;
290  if( ev.handler ) {
291  return ev.handler( curl, sslCtx, ev.data );
292  }
293  }
294 
295  return CURLE_ABORTED_BY_CALLBACK;
296  }
297 
298  int Easy::Pimpl::debug( CURL *, curl_infotype type, char *data, size_t size, void *userPtr )
299  {
300  if( auto impl = reinterpret_cast<Easy::Pimpl*>( userPtr ) )
301  {
302  auto &ev = impl->onDebug;
303  if( ev.handler ) {
304  ev.handler( nullptr, type, data, size, ev.data );
305  }
306  }
307 
308  return 0;
309  }
310 
311  /* Easy definitions
312  */
313 
314  Easy::Easy()
315  : _impl( new Pimpl() )
316  {
317  _impl->curl = curl_easy_init();
318 
319  if( _impl->curl == nullptr ) {
320  throw Exception( "can't init curl_easy interface" );
321  }
322 
323  // install default options
324  set( CURLOPT_USERAGENT, "curlite::Easy" );
325  }
326 
327  Easy::Easy( Easy &&other )
328  {
329  *this = std::move( other );
330  }
331 
333  {
334  if( auto ptr = release() ) {
335  curl_easy_cleanup( ptr );
336  }
337  }
338 
340  {
341  if( this != &other )
342  {
343  if( auto ptr = release() ) {
344  curl_easy_cleanup( ptr );
345  }
346 
347  _impl.swap( other._impl );
348  }
349 
350  return *this;
351  }
352 
353  Easy::operator bool() const
354  {
355  return _impl->err == CURLE_OK;
356  }
357 
358  bool Easy::operator << (std::istream &stream)
359  {
360  onRead( [&stream] (char *data, size_t size, size_t n, void *) -> size_t
361  {
362  stream.read( (char*) data, size * n );
363  return size_t( stream.gcount() );
364  } );
365 
366  return perform();
367  }
368 
369  bool Easy::operator >> (std::ostream &stream)
370  {
371  onWrite( [&stream] (char *data, size_t size, size_t n, void *) -> size_t
372  {
373  stream.write( (char*) data, size * n );
374  return stream ? size * n : 0;
375  } );
376 
377  return perform();
378  }
379 
381  {
382  CURL *curl = nullptr;
383  if( _impl ) {
384  std::swap( _impl->curl, curl );
385  }
386 
387  return curl;
388  }
389 
390  void Easy::reset()
391  {
392  curl_easy_reset( _impl->curl );
393 
394  _impl->err = CURLE_OK;
395 
396  onRead();
397  onWrite();
398  onHeader();
399  onProgress();
400  onDebug();
401  }
402 
404  {
405  return handleError(
406  curl_easy_perform( _impl->curl )
407  );
408  }
409 
410  size_t Easy::send( const char *buffer, size_t bufferSize )
411  {
412  size_t sent = 0;
413  auto err = curl_easy_send( _impl->curl, buffer, bufferSize, &sent );
414  return handleError( err ) ? sent : 0;
415  }
416 
417  size_t Easy::recv( char *buffer, size_t bufferSize )
418  {
419  size_t received = 0;
420  auto err = curl_easy_recv( _impl->curl, buffer, bufferSize, &received );
421  return handleError( err ) ? received : 0;
422  }
423 
424  bool Easy::pause( int bitmask )
425  {
426  return handleError(
427  curl_easy_pause( _impl->curl, bitmask )
428  );
429  }
430 
431  CURL* Easy::get() const
432  {
433  return _impl->curl;
434  }
435 
436  void Easy::setExceptionMode( bool throwExceptions )
437  {
438  _impl->throwExceptions = throwExceptions;
439  }
440 
441  bool Easy::exceptionMode() const
442  {
443  return _impl->throwExceptions;
444  }
445 
446  CURLcode Easy::error() const
447  {
448  return _impl->err;
449  }
450 
451  std::string Easy::errorString() const
452  {
453  return curl_easy_strerror( _impl->err );
454  }
455 
456  bool Easy::handleError( CURLcode code )
457  {
458  _impl->err = code;
459 
460  if( _impl->err != CURLE_OK && _impl->throwExceptions ) {
461  throw Exception( curl_easy_strerror(_impl->err) );
462  }
463 
464  return _impl->err == CURLE_OK;
465  }
466 
467  void Easy::setUserData( void *data )
468  {
469  _impl->userData = data;
470  }
471 
472  void *Easy::userData() const
473  {
474  return _impl->userData;
475  }
476 
477  std::string Easy::escape( std::string const &url )
478  {
479  std::string escaped;
480 
481  char *str = curl_easy_escape( _impl->curl, url.data(), url.size() );
482  if( str ) {
483  escaped = str;
484  curl_free( str );
485  }
486 
487  return escaped;
488  }
489 
490  std::string Easy::unescape( std::string const &url )
491  {
492  std::string unescaped;
493 
494  int outLength = 0; // who the hell decided to use int in curl_easy_unescape?
495  char *str = curl_easy_unescape( _impl->curl, url.data(), url.size(), &outLength );
496  if( str ) {
497  unescaped.assign( str, str + outLength );
498  curl_free( str );
499  }
500 
501  return unescaped;
502  }
503 
505  {
506  auto wrapper = [f]( char *data, size_t size, size_t n, void * ) -> size_t {
507  return f( data, size * n ) ? size * n : CURL_READFUNC_ABORT;
508  };
509 
510  onRead( f ? wrapper : ReadHandler() );
511  }
512 
514  {
515  auto wrapper = [f]( char *data, size_t size, size_t n, void * ) -> size_t {
516  return f( data, size * n ) ? size * n : 0;
517  };
518 
519  onWrite( f ? wrapper : WriteHandler() );
520  }
521 
523  {
524  auto wrapper = [f]( char *data, size_t size, size_t n, void * ) -> size_t {
525  return f( data, size * n ) ? size * n : 0;
526  };
527 
528  onHeader( f ? wrapper : WriteHandler() );
529  }
530 
532  {
533  auto wrapper = [f]( void *, curl_off_t dTotal, curl_off_t dCurrent, curl_off_t uTotal, curl_off_t uCurrent ) -> int {
534  return !f( dTotal, dCurrent, uTotal, uCurrent );
535  };
536 
537  onXferInfo( f ? wrapper : XferInfoHandler() );
538  }
539 
540  void Easy::onRead( ReadHandler f, void *data )
541  {
542  _impl->onRead.handler = f;
543  _impl->onRead.data = data;
544 
545  set( CURLOPT_READFUNCTION, f ? &Pimpl::read : nullptr );
546  set( CURLOPT_READDATA, f ? (void*) this->_impl.get() : nullptr );
547  }
548 
549  void Easy::onWrite( WriteHandler f, void *data )
550  {
551  _impl->onWrite.handler = f;
552  _impl->onWrite.data = data;
553 
554  set( CURLOPT_WRITEFUNCTION, f ? &Pimpl::write : nullptr );
555  set( CURLOPT_WRITEDATA, f ? (void*) this->_impl.get() : nullptr );
556  }
557 
558  void Easy::onHeader( WriteHandler f, void *data)
559  {
560  _impl->onHeader.handler = f;
561  _impl->onHeader.data = data;
562 
563  set( CURLOPT_HEADERFUNCTION, f ? &Pimpl::header : nullptr );
564  set( CURLOPT_HEADERDATA, f ? (void*) this->_impl.get() : nullptr );
565  }
566 
567  void Easy::onProgress( ProgressHandler f, void *data )
568  {
569  _impl->onProgress.handler = f;
570  _impl->onProgress.data = data;
571 
572  set( CURLOPT_PROGRESSFUNCTION, f ? &Pimpl::progress : nullptr );
573  set( CURLOPT_PROGRESSDATA, f ? (void*) this->_impl.get() : nullptr );
574  set( CURLOPT_NOPROGRESS, f ? false : true );
575  }
576 
577  void Easy::onDebug( DebugHandler f, void *data)
578  {
579  _impl->onDebug.handler = f;
580  _impl->onDebug.data = data;
581 
582  set( CURLOPT_DEBUGFUNCTION, f ? &Pimpl::debug : nullptr );
583  set( CURLOPT_DEBUGDATA, f ? (void*) this->_impl.get() : nullptr );
584  set( CURLOPT_VERBOSE, f ? true : false );
585  }
586 
587  void Easy::onIoctl( IoctlHandler f, void *data)
588  {
589  _impl->onIoctl.handler = f;
590  _impl->onIoctl.data = data;
591 
592  set( CURLOPT_IOCTLFUNCTION, f ? &Pimpl::ioctl : nullptr );
593  set( CURLOPT_IOCTLDATA, f ? (void*) this->_impl.get() : nullptr );
594  }
595 
596  void Easy::onSeek( SeekHandler f, void *data)
597  {
598  _impl->onSeek.handler = f;
599  _impl->onSeek.data = data;
600 
601  set( CURLOPT_SEEKFUNCTION, f ? &Pimpl::seek : nullptr );
602  set( CURLOPT_SEEKDATA, f ? (void*) this->_impl.get() : nullptr );
603  }
604 
605  void Easy::onFnMatch( FnMatchHandler f, void *data)
606  {
607  _impl->onFnMatch.handler = f;
608  _impl->onFnMatch.data = data;
609 
610  set( CURLOPT_FNMATCH_FUNCTION, f ? &Pimpl::fnMatch : nullptr );
611  set( CURLOPT_FNMATCH_DATA, f ? (void*) this->_impl.get() : nullptr );
612  }
613 
614  void Easy::onXferInfo( XferInfoHandler f, void *data)
615  {
616  _impl->onXferInfo.handler = f;
617  _impl->onXferInfo.data = data;
618 
619  set( CURLOPT_XFERINFOFUNCTION, f ? &Pimpl::xferInfo : nullptr );
620  set( CURLOPT_XFERINFODATA, f ? (void*) this->_impl.get() : nullptr );
621  set( CURLOPT_NOPROGRESS, f ? false : true );
622  }
623 
625  {
626  _impl->onOpenSocket.handler = f;
627  _impl->onOpenSocket.data = data;
628 
629  set( CURLOPT_OPENSOCKETFUNCTION, f ? &Pimpl::openSocket : nullptr );
630  set( CURLOPT_OPENSOCKETDATA, f ? (void*) this->_impl.get() : nullptr );
631  }
632 
634  {
635  _impl->onCloseSocket.handler = f;
636  _impl->onCloseSocket.data = data;
637 
638  set( CURLOPT_CLOSESOCKETFUNCTION, f ? &Pimpl::closeSocket : nullptr );
639  set( CURLOPT_CLOSESOCKETDATA, f ? (void*) this->_impl.get() : nullptr );
640  }
641 
642  void Easy::onSockOpt( SockOptHandler f, void *data)
643  {
644  _impl->onSockOpt.handler = f;
645  _impl->onSockOpt.data = data;
646 
647  set( CURLOPT_SOCKOPTFUNCTION, f ? &Pimpl::sockOpt : nullptr );
648  set( CURLOPT_SOCKOPTDATA, f ? (void*) this->_impl.get() : nullptr );
649  }
650 
652  {
653  _impl->onChunkBegin.handler = f;
654  _impl->onChunkBegin.data = data;
655 
656  set( CURLOPT_CHUNK_BGN_FUNCTION, f ? &Pimpl::chunkBegin : nullptr );
657  set( CURLOPT_CHUNK_DATA, f ? (void*) this->_impl.get() : nullptr );
658  }
659 
660  void Easy::onChunkEnd( ChunkEndHandler f, void *data)
661  {
662  _impl->onChunkEnd.handler = f;
663  _impl->onChunkEnd.data = data;
664 
665  set( CURLOPT_CHUNK_END_FUNCTION, f ? &Pimpl::chunkEnd : nullptr );
666  set( CURLOPT_CHUNK_DATA, f ? (void*) this->_impl.get() : nullptr );
667  }
668 
670  {
671  _impl->onSslContext.handler = f;
672  _impl->onSslContext.data = data;
673 
674  set( CURLOPT_SSL_CTX_FUNCTION, f ? &Pimpl::sslContext : nullptr );
675  set( CURLOPT_SSL_CTX_DATA, f ? (void*) this->_impl.get() : nullptr );
676  }
677 
678  std::ostream &operator << ( std::ostream &stream, Easy &curlite )
679  {
680  curlite >> stream;
681  return stream;
682  }
683 
684  std::istream &operator >> ( std::istream &stream, Easy &curlite )
685  {
686  curlite << stream;
687  return stream;
688  }
689 
690  /* Definition of curlite::List
691  */
692 
693  List::List( curl_slist *list )
694  : _list( list )
695  {
696  }
697 
698  List::List( std::vector<std::string> const &values )
699  {
700  append( values );
701  }
702 
704  {
705  if( auto ptr = release() ) {
706  curl_slist_free_all( ptr );
707  }
708  }
709 
710  List::List( List &&other )
711  : _list( nullptr )
712  {
713  *this = std::move( other );
714  }
715 
717  {
718  if( this != &other )
719  {
720  if( auto ptr = release() ) {
721  curl_slist_free_all( ptr );
722  }
723 
724  std::swap( _list, other._list );
725  }
726 
727  return *this;
728  }
729 
730  curl_slist *List::get() const
731  {
732  return _list;
733  }
734 
735  curl_slist *List::release()
736  {
737  curl_slist *list = nullptr;
738  std::swap( list, _list );
739  return list;
740  }
741 
742  List &List::append( char const *s )
743  {
744  _list = curl_slist_append( _list, s );
745  return *this;
746  }
747 
748  List &List::append( std::vector<std::string> const &values )
749  {
750  for( auto it = values.begin(); it != values.end(); ++it ) {
751  append( it->c_str() );
752  }
753 
754  return *this;
755  }
756 
757  List &List::operator << ( char const *s )
758  {
759  return append( s );
760  }
761 
762  /* Definition of curlite::Form
763  */
764 
765  Form::Form() : _first( nullptr ), _last( nullptr )
766  {
767  }
768 
769  Form::Form( std::vector<curl_forms> const &forms )
770  : _first( nullptr ), _last( nullptr )
771  {
772  add( forms );
773  }
774 
775  Form::Form( Form &&other )
776  : _first( nullptr ), _last( nullptr )
777  {
778  std::swap( _first, other._first );
779  std::swap( _last, other._last );
780  }
781 
783  {
784  if( auto ptr = release().first ) {
785  curl_formfree( ptr );
786  }
787  }
788 
790  {
791  if( this != &other )
792  {
793  if( auto ptr = release().first ) {
794  curl_formfree( ptr );
795  }
796 
797  std::swap( _first, other._first );
798  std::swap( _last, other._last );
799  }
800 
801  return *this;
802  }
803 
804  curl_httppost *Form::get() const
805  {
806  return _first;
807  }
808 
809  std::pair<curl_httppost*, curl_httppost*> Form::release()
810  {
811  auto r = std::make_pair<curl_httppost*, curl_httppost*>( nullptr, nullptr );
812 
813  std::swap( r.first, _first );
814  std::swap( r.second, _last );
815 
816  return r;
817  }
818 
819  bool Form::add( std::vector<curl_forms> const &forms )
820  {
821  auto err = curl_formadd( &_first, &_last, CURLFORM_ARRAY, forms.data(), CURLFORM_END );
822  return err == CURL_FORMADD_OK;
823  }
824 
825  /* Other functions
826  */
827 
828  bool global_init( long flags )
829  {
830  return curl_global_init( flags ) == 0;
831  }
832 
834  {
835  curl_global_cleanup();
836  }
837 
838  std::string version()
839  {
840  return std::string( curl_version() );
841  }
842 
843  curl_version_info_data *versionInfo( CURLversion type )
844  {
845  return curl_version_info( type );
846  }
847 
848  Easy download( std::string const &url, std::ostream &ostr, bool followRedirect, bool throwExceptions )
849  {
850  Easy c;
851  c.setExceptionMode( throwExceptions );
852  c.set( CURLOPT_URL, url );
853  c.set( CURLOPT_FOLLOWLOCATION, followRedirect );
854 
855  c >> ostr;
856 
857  return std::move( c );
858  }
859 
860  Easy upload( std::istream &istr,
861  std::string const &url,
862  std::string const &username,
863  std::string const &password,
864  curl_off_t size,
865  bool throwExceptions )
866  {
867  Easy c;
868  c.setExceptionMode( throwExceptions );
869  c.set( CURLOPT_URL, url );
870  c.set( CURLOPT_USERNAME, username );
871  c.set( CURLOPT_PASSWORD, password );
872  c.set( CURLOPT_INFILESIZE_LARGE, size );
873  c.set( CURLOPT_UPLOAD, true );
874 
875  List headers;
876  if( size == -1 ) {
877  headers << "Transfer-Encoding: chunked";
878  headers << "Expect:";
879 
880  // if it's not http(s) upload then the option will be ignored
881  c.set( CURLOPT_HTTPHEADER, headers.get() );
882  }
883 
884  istr >> c;
885 
886  // reset the option to avoid access violation (if a client reuses the Easy object)
887  c.set( CURLOPT_HTTPHEADER, nullptr );
888 
889  return std::move( c );
890  }
891 
892 } // end of namespace <curlite>
static int xferInfo(void *userPtr, curl_off_t dTotal, curl_off_t dCurrent, curl_off_t uTotal, curl_off_t uCurrent)
Definition: curlite.cpp:207
Event< XferInfoHandler > onXferInfo
Definition: curlite.cpp:72
void reset()
Definition: curlite.cpp:390
void * data
Definition: curlite.cpp:53
Handler< curl_opensocket_callback >::type OpenSocketHandler
Definition: curlite.hpp:58
Handler< curl_ssl_ctx_callback >::type SslContextHandler
Definition: curlite.hpp:63
static int sockOpt(void *userPtr, curl_socket_t socket, curlsocktype purpose)
Definition: curlite.cpp:272
void onWrite_(SimplifiedDataHandler f)
Definition: curlite.cpp:513
Handler< curl_fnmatch_callback >::type FnMatchHandler
Definition: curlite.hpp:54
Event< CloseSocketHandler > onCloseSocket
Definition: curlite.cpp:77
curl_slist * release()
Definition: curlite.cpp:735
void onWrite(WriteHandler f=WriteHandler(), void *data=nullptr)
Definition: curlite.cpp:549
bool exceptionMode() const
Definition: curlite.cpp:441
Event< OpenSocketHandler > onOpenSocket
Definition: curlite.cpp:76
void onProgress(ProgressHandler f=ProgressHandler(), void *data=nullptr)
Definition: curlite.cpp:567
std::function< bool(char *, size_t)> SimplifiedDataHandler
Definition: curlite.hpp:102
static curl_socket_t openSocket(void *userPtr, curlsocktype purpose, curl_sockaddr *address)
Definition: curlite.cpp:246
std::function< bool(curl_off_t, curl_off_t, curl_off_t, curl_off_t)> SimplifiedProgressHandler
Definition: curlite.hpp:103
Handler< curl_chunk_end_callback >::type ChunkEndHandler
Definition: curlite.hpp:53
Handler< curl_debug_callback >::type DebugHandler
Definition: curlite.hpp:61
void setUserData(void *data)
Definition: curlite.cpp:467
Easy upload(std::istream &istr, std::string const &url, std::string const &username="", std::string const &password="", curl_off_t size=-1, bool throwExceptions=true)
Definition: curlite.cpp:860
void onSslContext(SslContextHandler f=SslContextHandler(), void *data=nullptr)
Definition: curlite.cpp:669
Handler< curl_ioctl_callback >::type IoctlHandler
Definition: curlite.hpp:60
curl_version_info_data * versionInfo(CURLversion type=CURLVERSION_NOW)
Definition: curlite.cpp:843
bool handleError(CURLcode code)
Definition: curlite.cpp:456
static int progress(void *userPtr, double dTotal, double dCurrent, double uTotal, double uCurrent)
Definition: curlite.cpp:194
void onSeek(SeekHandler f=SeekHandler(), void *data=nullptr)
Definition: curlite.cpp:596
bool perform()
Definition: curlite.cpp:403
void onOpenSocket(OpenSocketHandler f=OpenSocketHandler(), void *data=nullptr)
Definition: curlite.cpp:624
static long chunkBegin(const void *transferInfo, void *userPtr, int remains)
Definition: curlite.cpp:220
static CURLcode sslContext(CURL *curl, void *sslCtx, void *userPtr)
Definition: curlite.cpp:285
void onProgress_(SimplifiedProgressHandler f)
Definition: curlite.cpp:531
Handler< curl_read_callback >::type ReadHandler
Definition: curlite.hpp:56
Handler< curl_write_callback >::type WriteHandler
Definition: curlite.hpp:51
size_t send(const char *buffer, size_t bufferSize)
Definition: curlite.cpp:410
Handler< curl_seek_callback >::type SeekHandler
Definition: curlite.hpp:55
void onCloseSocket(CloseSocketHandler f=CloseSocketHandler(), void *data=nullptr)
Definition: curlite.cpp:633
List(List const &other)
curl_slist * _list
Definition: curlite.hpp:379
List & operator<<(char const *s)
Definition: curlite.cpp:757
bool global_init(long flags=CURL_GLOBAL_ALL)
Definition: curlite.cpp:828
std::unique_ptr< Pimpl > _impl
Definition: curlite.hpp:92
Event< SockOptHandler > onSockOpt
Definition: curlite.cpp:75
void onHeader_(SimplifiedDataHandler f)
Definition: curlite.cpp:522
Handler< curl_closesocket_callback >::type CloseSocketHandler
Definition: curlite.hpp:59
void * userData() const
Definition: curlite.cpp:472
Event< SslContextHandler > onSslContext
Definition: curlite.cpp:78
Event< FnMatchHandler > onFnMatch
Definition: curlite.cpp:70
bool operator<<(std::istream &stream)
Definition: curlite.cpp:358
curl_httppost * get() const
Definition: curlite.cpp:804
Event< ReadHandler > onRead
Definition: curlite.cpp:65
void operator=(Easy const &other)
bool pause(int bitmask)
Definition: curlite.cpp:424
static int fnMatch(void *userPtr, const char *pattern, const char *string)
Definition: curlite.cpp:155
static size_t header(char *data, size_t size, size_t n, void *userPtr)
Definition: curlite.cpp:142
std::pair< curl_httppost *, curl_httppost * > release()
Definition: curlite.cpp:809
std::string version()
Definition: curlite.cpp:838
void operator=(Form const &other)
CURL * release()
Definition: curlite.cpp:380
void onRead(ReadHandler f=ReadHandler(), void *data=nullptr)
Definition: curlite.cpp:540
CURLcode error() const
Definition: curlite.cpp:446
void setExceptionMode(bool throwExceptions)
Definition: curlite.cpp:436
Handler< curl_xferinfo_callback >::type XferInfoHandler
Definition: curlite.hpp:50
static size_t read(char *data, size_t size, size_t n, void *userPtr)
Definition: curlite.cpp:116
void onDebug(DebugHandler f=DebugHandler(), void *data=nullptr)
Definition: curlite.cpp:577
virtual ~Easy()
Definition: curlite.cpp:332
curl_httppost * _last
Definition: curlite.hpp:426
Easy download(std::string const &url, std::ostream &ostr, bool followRedirect=true, bool throwExceptions=true)
Definition: curlite.cpp:848
void onHeader(WriteHandler f=WriteHandler(), void *data=nullptr)
Definition: curlite.cpp:558
bool operator>>(std::ostream &stream)
Definition: curlite.cpp:369
curl_slist * get() const
Definition: curlite.cpp:730
size_t recv(char *buffer, size_t bufferSize)
Definition: curlite.cpp:417
bool set(CURLoption opt, ValueType value)
Definition: curlite.hpp:297
bool add(std::vector< curl_forms > const &forms)
Definition: curlite.cpp:819
static long chunkEnd(void *userPtr)
Definition: curlite.cpp:233
std::string escape(std::string const &url)
Definition: curlite.cpp:477
Event< IoctlHandler > onIoctl
Definition: curlite.cpp:68
std::string errorString() const
Definition: curlite.cpp:451
void onIoctl(IoctlHandler f=IoctlHandler(), void *data=nullptr)
Definition: curlite.cpp:587
std::string unescape(std::string const &url)
Definition: curlite.cpp:490
curl_httppost * _first
Definition: curlite.hpp:425
void operator=(List const &other)
void onXferInfo(XferInfoHandler f=XferInfoHandler(), void *data=nullptr)
Definition: curlite.cpp:614
void onRead_(SimplifiedDataHandler f)
Definition: curlite.cpp:504
Event< ChunkEndHandler > onChunkEnd
Definition: curlite.cpp:74
CURL * get() const
Definition: curlite.cpp:431
static size_t write(char *data, size_t size, size_t n, void *userPtr)
Definition: curlite.cpp:129
void onSockOpt(SockOptHandler f=SockOptHandler(), void *data=nullptr)
Definition: curlite.cpp:642
Handler< curl_progress_callback >::type ProgressHandler
Definition: curlite.hpp:49
Event< SeekHandler > onSeek
Definition: curlite.cpp:69
static int seek(void *userPtr, curl_off_t offset, int origin)
Definition: curlite.cpp:168
Event< ChunkBeginHandler > onChunkBegin
Definition: curlite.cpp:73
void global_cleanup()
Definition: curlite.cpp:833
static int closeSocket(void *userPtr, curl_socket_t socket)
Definition: curlite.cpp:259
Event< DebugHandler > onDebug
Definition: curlite.cpp:79
static int debug(CURL *, curl_infotype type, char *data, size_t size, void *userPtr)
Definition: curlite.cpp:298
void onChunkBegin(ChunkBeginHandler f=ChunkBeginHandler(), void *data=nullptr)
Definition: curlite.cpp:651
void onFnMatch(FnMatchHandler f=FnMatchHandler(), void *data=nullptr)
Definition: curlite.cpp:605
static curlioerr ioctl(CURL *handle, int cmd, void *userPtr)
Definition: curlite.cpp:181
void onChunkEnd(ChunkEndHandler f=ChunkEndHandler(), void *data=nullptr)
Definition: curlite.cpp:660
Handler< curl_chunk_bgn_callback >::type ChunkBeginHandler
Definition: curlite.hpp:52
HandlerType handler
Definition: curlite.cpp:52
List & append(char const *s)
Definition: curlite.cpp:742
Event< WriteHandler > onHeader
Definition: curlite.cpp:67
Event< ProgressHandler > onProgress
Definition: curlite.cpp:71
Event< WriteHandler > onWrite
Definition: curlite.cpp:66
Handler< curl_sockopt_callback >::type SockOptHandler
Definition: curlite.hpp:57


fanuc_post_processor
Author(s): Victor Lamoine - Institut Maupertuis
autogenerated on Mon Jun 10 2019 13:16:55