2005-08-09 22:01:28 +00:00
|
|
|
// Berkeley Open Infrastructure for Network Computing
|
|
|
|
// http://boinc.berkeley.edu
|
|
|
|
// Copyright (C) 2005 University of California
|
|
|
|
//
|
|
|
|
// This is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation;
|
|
|
|
// either version 2.1 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This software is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
// See the GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// To view the GNU Lesser General Public License visit
|
|
|
|
// http://www.gnu.org/copyleft/lesser.html
|
|
|
|
// or write to the Free Software Foundation, Inc.,
|
|
|
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
|
|
#ifndef _NET_XFER_
|
|
|
|
#define _NET_XFER_
|
|
|
|
|
|
|
|
#ifndef _WIN32
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <vector>
|
|
|
|
#endif
|
2005-08-16 20:48:21 +00:00
|
|
|
#include <curl/curl.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include "network.h"
|
2005-08-09 22:01:28 +00:00
|
|
|
|
2005-08-12 17:39:56 +00:00
|
|
|
#ifndef _MAX_PATH
|
|
|
|
#define _MAX_PATH 256
|
|
|
|
#endif
|
|
|
|
|
2005-08-09 22:01:28 +00:00
|
|
|
extern CURLM* g_curlMulti; // the global libcurl multi handle
|
|
|
|
|
|
|
|
// The following classes implement polling (non-blocking) I/O
|
|
|
|
// between a disk file (or memory block) and a socket
|
|
|
|
|
|
|
|
#define MAX_BLOCKSIZE 16384
|
|
|
|
|
|
|
|
// global functions for starting & stopping libcurl
|
|
|
|
extern int curl_init();
|
|
|
|
extern int curl_cleanup();
|
|
|
|
|
|
|
|
// represents a network connection, either being accessed directly
|
|
|
|
// or being transferred to/from a file
|
|
|
|
//
|
2005-08-24 17:50:48 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
net_xfer object status codes (using libcurl):
|
|
|
|
|
|
|
|
nxf->response maps to HTTP_STATUS_* (from http_curl.h)
|
|
|
|
nxf->http_op_state maps to HTTP_STATE_* (from http_curl.h)
|
|
|
|
nxf->CurlError is a curl specific code (maps to the CURLE_* enums in curl/curl.h)
|
|
|
|
nxf->strCurlError is a human-readable msg (i.e. "couldn't connect to server")
|
|
|
|
*/
|
|
|
|
|
2005-08-09 22:01:28 +00:00
|
|
|
class NET_XFER {
|
|
|
|
public:
|
|
|
|
FILE* fileIn;
|
|
|
|
FILE* fileOut; // CMC need an output file for POST responses
|
|
|
|
CURL* curlEasy; // the "easy curl" handle for this net_xfer request
|
|
|
|
struct curl_slist *pcurlList; // curl slist for http headers
|
|
|
|
struct curl_httppost *pcurlFormStart; // a pointer to a form item for POST
|
|
|
|
struct curl_httppost *pcurlFormEnd; // a pointer to a form item for POST
|
|
|
|
unsigned char* pByte; // pointer to bytes for reading via libcurl_read function
|
|
|
|
long lSeek; // this is a pointer within the file we're reading
|
|
|
|
char infile[_MAX_PATH];
|
|
|
|
char outfile[_MAX_PATH];
|
|
|
|
bool bTempOutfile; // CMC -- flag that outfile is really a tempfile we should delete
|
|
|
|
char* req1;
|
|
|
|
bool bSentHeader; // CMC -- a flag that I already sent the header
|
2005-08-24 17:50:48 +00:00
|
|
|
CURLcode CurlResult; // CMC -- send up curl result code
|
|
|
|
char strCurlResult[_MAX_PATH]; // CMC -- 'human-readable' string with result info
|
2005-08-09 22:01:28 +00:00
|
|
|
|
|
|
|
// int socket; // CMC -- deprecated, net_xfer's via curlEasy handle above
|
|
|
|
char hostname[256]; // The host we're connecting to (possibly a proxy)
|
|
|
|
bool is_connected;
|
|
|
|
bool want_download; // at most one should be true
|
|
|
|
bool want_upload;
|
|
|
|
bool do_file_io;
|
|
|
|
// If true: poll() should transfer data to/from file
|
|
|
|
// (in which case "file" and blocksize are relevant)
|
|
|
|
// If false: set io_ready (higher layers will do I/O)
|
|
|
|
bool io_done;
|
|
|
|
// set to true when the current transfer is over:
|
|
|
|
// - the transfer timed out (not activity for a long time)
|
|
|
|
// - network connect failed
|
|
|
|
// - got EOF on socket read (0 bytes, select indicated I/O ready)
|
|
|
|
// - error on disk write (e.g. volume full)
|
|
|
|
// - reached end of disk file on upload
|
|
|
|
// - got file read error on upload
|
|
|
|
// - write to socket failed on upload
|
|
|
|
bool io_ready;
|
|
|
|
// Signals higher layers that they can read or write socket now
|
|
|
|
// (used if !do_file_io)
|
|
|
|
long error;
|
|
|
|
long response;
|
|
|
|
int port;
|
|
|
|
int blocksize;
|
|
|
|
double start_time;
|
|
|
|
double xfer_speed;
|
|
|
|
double bytes_xferred; // bytes transferred in this session
|
|
|
|
double content_length;
|
|
|
|
char file_read_buf[MAX_BLOCKSIZE];
|
|
|
|
int file_read_buf_offset, file_read_buf_len;
|
|
|
|
int seconds_until_timeout;
|
|
|
|
|
|
|
|
// CMC - moved from http_op
|
|
|
|
int http_op_state; // values below
|
|
|
|
int http_op_type;
|
|
|
|
int http_op_retval;
|
|
|
|
|
|
|
|
NET_XFER();
|
|
|
|
~NET_XFER();
|
|
|
|
void reset();
|
|
|
|
void init(char* host, int port, int blocksize);
|
|
|
|
int get_ip_addr(int &ip_addr);
|
|
|
|
//int open_server();
|
|
|
|
void close_socket();
|
|
|
|
void close_file();
|
|
|
|
// int do_xfer(int&); // CMC not needed for libcurl
|
|
|
|
void update_speed();
|
|
|
|
void got_error();
|
|
|
|
char* get_hostname();
|
|
|
|
bool check_timeout(bool);
|
|
|
|
void reset_timeout();
|
|
|
|
};
|
|
|
|
|
|
|
|
// bandwidth limitation is implemented at this level, as follows:
|
|
|
|
// There are limits max_bytes_sec_up and max_bytes_sec_down.
|
|
|
|
// We keep track of the last time and bytes_left_up and bytes_left_down;
|
|
|
|
// Each second we reset these to zero.
|
|
|
|
|
|
|
|
class NET_XFER_SET {
|
|
|
|
std::vector<NET_XFER*> net_xfers;
|
|
|
|
public:
|
|
|
|
NET_XFER_SET();
|
|
|
|
double max_bytes_sec_up, max_bytes_sec_down;
|
|
|
|
// user-specified limits on throughput
|
|
|
|
double bytes_left_up, bytes_left_down;
|
|
|
|
// bytes left to transfer in the current second
|
|
|
|
double bytes_up, bytes_down;
|
|
|
|
// total bytes transferred
|
|
|
|
bool up_active, down_active;
|
|
|
|
// has there been transfer activity since last call to check_active()?
|
|
|
|
int last_time;
|
|
|
|
int insert(NET_XFER*);
|
|
|
|
int remove(NET_XFER*);
|
2005-08-16 20:48:21 +00:00
|
|
|
|
|
|
|
void get_fdset(FDSET_GROUP&);
|
|
|
|
void got_select(FDSET_GROUP&, double);
|
|
|
|
#if 0
|
2005-08-09 22:01:28 +00:00
|
|
|
bool poll();
|
|
|
|
int net_sleep(double);
|
|
|
|
int do_select(double& bytes_transferred, double timeout);
|
2005-08-16 20:48:21 +00:00
|
|
|
#endif
|
2005-08-09 22:01:28 +00:00
|
|
|
NET_XFER* lookup_curl(CURL* pcurl); // lookup by easycurl handle
|
|
|
|
void check_active(bool&, bool&);
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // _H
|