Download.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /******************************************************************************
  2. Use 'Download' to download a single file from the internet.
  3. 'Download' can be also used to upload files when 'File post' parameter is specified,
  4. in that case, POST command will be used instead of GET.
  5. You can use following PHP code on the server to process the file:
  6. <?php
  7. function LogN($text) {error_log($text."\n", 3, "log.txt");}
  8. $error =$_FILES["file"]["error" ]; // if error occurred during file receiving
  9. $file_size=$_FILES["file"]["size" ]; // file size
  10. $temp_name=$_FILES["file"]["tmp_name"]; // temporary file name
  11. $file_name="Uploads/file"; // desired file name
  12. if($error>0) // if any error occurred
  13. {
  14. LogN('Error:'.$error);
  15. }else
  16. {
  17. LogN("File Size: ".$file_size);
  18. LogN("Temp Name: ".$temp_name);
  19. if(file_exists($file_name)) // check if such file already exists
  20. {
  21. LogN($file_name." already exists"); // don't store it
  22. }else
  23. {
  24. move_uploaded_file($temp_name, $file_name); // store the file
  25. }
  26. }
  27. ?>
  28. /******************************************************************************/
  29. enum DWNL_STATE : Byte // Download States
  30. {
  31. DWNL_NONE , // nothing
  32. DWNL_CONNECTING, // waiting for connection
  33. DWNL_AUTH , // authenticating (this occurs for secure https connections only)
  34. DWNL_SENDING , // sending request and 'post' data if specified
  35. DWNL_DOWNLOAD , // downloading
  36. DWNL_DONE , // done
  37. DWNL_ERROR , // error encountered
  38. };
  39. /******************************************************************************/
  40. enum HTTP_TYPE : Byte // HTTP Parameter Type
  41. {
  42. HTTP_GET , // get parameter
  43. HTTP_POST , // post parameter
  44. HTTP_HEADER, // header parameter
  45. };
  46. STRUCT(HTTPParam , TextParam) // optional parameter that can be passed to the 'Download'
  47. //{
  48. HTTP_TYPE type; // parameter type
  49. HTTPParam& set(C Str &name, C Str &value, HTTP_TYPE type=HTTP_GET) {super::set(name, value); T.type=type; return T;}
  50. HTTPParam() {type=HTTP_GET;}
  51. static Str8 Encode(C MemPtr<HTTPParam> &params); // encode 'params' array into string
  52. };
  53. /******************************************************************************/
  54. const_mem_addr struct Download // File Downloader !! must be stored in constant memory address !!
  55. {
  56. // manage
  57. Download& del ( Int milliseconds=-1 ); // wait 'milliseconds' time for thread to exit and delete (<0 = infinite wait)
  58. Download& create(C Str &url, C MemPtr<HTTPParam> &params=null, const_mem_addr File *post=null, Long max_post_size=-1, Long offset=0, Long size=-1, Bool paused=false, Bool ignore_auth_result=false); // download 'url' file, 'params'=optional parameters that you can pass if the 'url' is a php script, 'post'=data to be sent to the specified address (if this is null then HTTP GET is used, otherwise HTTP POST is used, 'post' File must point to a constant memory address as that pointer will be used until the data has been fully sent), 'max_post_size'=number of bytes to send (-1=all remaining), 'offset'=offset position of the file data to download, use this for example if you wish to resume previous download by starting from 'offset' position, 'size'=number of bytes to download (-1=all remaining), warning: some servers don't support manual specifying 'offset' and 'size', 'paused'=if create paused, 'ignore_auth_result'=if ignore authorization results and continue even when they failed
  59. // operations
  60. Download& pause ( ); // pause downloading
  61. Download& resume( ); // resume downloading
  62. Download& stop ( ); // request the download to be stopped and return immediately after that, without waiting for the thread to exit
  63. Download& wait (Int milliseconds=-1); // wait for the download thread to exit (<0 = infinite wait)
  64. // get
  65. DWNL_STATE state ()C {return _state ;} // get download state
  66. UShort code ()C {return _code ;} // get HTTP status code, or 0 if unavailable
  67. Ptr data ()C {return _data ;} // get downloaded data , this will be valid only in DWNL_DONE state
  68. Long offset ()C {return _offset ;} // get offset of file
  69. Long done ()C {return _done ;} // get number of downloaded bytes
  70. Long size ()C {return _size ;} // get number of bytes to download, this will be valid only in DWNL_DONE state, in DWNL_DOWNLOAD state the value will be either valid or equal to -1 if the size is still unknown
  71. Long totalSize ()C {return _total_size ;} // get total file size , this will be valid only in DWNL_DONE state, in DWNL_DOWNLOAD state the value will be either valid or equal to -1 if the size is still unknown
  72. Long sent ()C {return _sent ;} // get number of sent bytes
  73. Long toSend ()C {return _to_send ;} // get number of bytes to send
  74. Long totalSent ()C {return _total_sent ;} // get total number of bytes that were sent , including ovearhead - headers, redirections and SSL/TLS/HTTPS handshake/data
  75. Long totalReceived ()C {return _total_rcvd ;} // get total number of bytes that were received , including ovearhead - headers, redirections and SSL/TLS/HTTPS handshake/data
  76. Long totalTransferred()C {return _total_sent+_total_rcvd;} // get total number of bytes that were transferred, including ovearhead - headers, redirections and SSL/TLS/HTTPS handshake/data
  77. C Str& url ()C {return _url ;} // get url address
  78. C DateTime& modifyTimeUTC ()C {return _modif_time ;} // get modification time in UTC time zone of the downloaded file, if value is provided then it will be available starting from DWNL_DOWNLOAD state
  79. Bool paused ()C {return _thread.wantPause() ;} // get if download is currently requested to be paused
  80. Bool authFailed ()C; // get if authorization failed, this will be valid after DWNL_AUTH finished
  81. #if EE_PRIVATE
  82. void parse (Byte *data, Int size);
  83. Int send (CPtr data, Int size);
  84. Int receive( Ptr data, Int size);
  85. void finish ();
  86. void zero ();
  87. Bool func ();
  88. void delPartial();
  89. Bool error (); // !! this is not thread-safe !! set DWNL_ERROR state, you can signal that an error has encountered for example when invalid data downloaded, always returns false
  90. #endif
  91. ~Download() {del();}
  92. Download();
  93. explicit Download(C Str &url, C MemPtr<HTTPParam> &params=null, const_mem_addr File *post=null, Long max_post_size=-1, Long offset=0, Long size=-1, Bool paused=false);
  94. #if !EE_PRIVATE
  95. private:
  96. #endif
  97. #if EE_PRIVATE
  98. enum PARSE_MODE : Byte
  99. {
  100. PARSE_DATA_SIZE,
  101. PARSE_DATA ,
  102. PARSE_SKIP_LINE,
  103. PARSE_END ,
  104. };
  105. enum FLAGS
  106. {
  107. CHUNKED =1<<0, // if download is chunked
  108. HAS_ADDRS_HEADER=1<<1, // this flag is used to check if has "addresses" in connecting state, and "header" in downloading state
  109. AUTH_IGNORE =1<<2, // ignore authorization results and continue with download
  110. AUTH_FAILED =1<<3, // authorization failed
  111. };
  112. Bool chunked ()C {return FlagTest(_flags, CHUNKED);}
  113. Bool hasAddrsHeader()C {return FlagTest(_flags, HAS_ADDRS_HEADER);}
  114. #endif
  115. Byte _flags, _parse;
  116. DWNL_STATE _state;
  117. UShort _code;
  118. Int _expected_size, _pre_send, _pos_send;
  119. Long _offset, _done, _size, _total_size, _sent, _to_send, _total_sent, _total_rcvd;
  120. Ptr _data;
  121. File *_post_file;
  122. DateTime _modif_time;
  123. Str8 _url_full, _header;
  124. Str _url;
  125. Thread _thread;
  126. SecureSocket _socket;
  127. Memb<Byte> _memb;
  128. Mems<Byte> _message;
  129. Mems<SockAddr> _addrs;
  130. #if WEB
  131. Ptr _js_download;
  132. #endif
  133. NO_COPY_CONSTRUCTOR(Download);
  134. };
  135. /******************************************************************************/
  136. #if EE_PRIVATE
  137. #if HAS_THREADS
  138. #define DOWNLOAD_WAIT_TIME 1
  139. #else
  140. #define DOWNLOAD_WAIT_TIME 0
  141. #endif
  142. #endif
  143. /******************************************************************************/