📄 connection.c
字号:
case CONREJECT: return (_("Connect Refused")); case REMOTEFATAL: return (_("Remote Fatal")); case LOCALFATAL: return (_("Local Fatal")); case TIMEDOUT: return (_("Timed Out")); case MAXTRYS: return (_("Max attempts reached")); default: return (_("Unkown Status!")); }}pthread_mutex_t connection_msg_mutex = PTHREAD_MUTEX_INITIALIZER;/*calls the msg_proc function if not null */void connection_show_message(connection_t * connection, const char *format, ...){ va_list args; char message[MAX_MSG_SIZE + 1]; pthread_mutex_lock(&connection_msg_mutex); va_start(args, format); vsnprintf(message, MAX_MSG_SIZE, format, args); va_end(args); if (connection->msg_proc) connection->msg_proc(message, connection->cb_data); /*FIXME: Remove this later */ printf("%s\n", message); pthread_mutex_unlock(&connection_msg_mutex);}/* Returns the total number of bytes that have been saved to the file*/long proz_connection_get_total_bytes_got(connection_t * connection){ long ret; pthread_mutex_lock(&connection->access_mutex); ret = connection->remote_bytes_received; pthread_mutex_unlock(&connection->access_mutex); return ret;}/***************************************************************************** Returns the total number of bytes that has being got from the server by this connection.******************************************************************************/long proz_connection_get_total_remote_bytes_got(connection_t * connection){ long ret; pthread_mutex_lock(&connection->access_mutex); ret = (connection->remote_bytes_received - (connection->remote_startpos-connection->orig_remote_startpos)); pthread_mutex_unlock(&connection->access_mutex); return ret;}void proz_get_url_info_loop(connection_t * connection, pthread_t *thread){ assert(connection); assert(thread); connection->running = TRUE; pthread_create(thread, NULL, (void *(*)(void *)) get_url_info_loop, (void *) connection);}/************************************************************************This Fucntion will retreive info about the given url in the connection, handling conditions like redirection from http to ftp etc *************************************************************************/void get_url_info_loop(connection_t * connection){ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); /*TODO Should we try to make it broadcast a condition to the other threads? */ pthread_mutex_lock(&connection->access_mutex); connection->running = TRUE; pthread_mutex_unlock(&connection->access_mutex); do { switch (connection->u.proto) { case URLHTTP: connection->err = http_get_url_info_loop(connection); break; case URLFTP: connection->err = ftp_get_url_info_loop(connection); break; default: proz_die(_("Error: unsupported protocol")); } if (connection->err == NEWLOCATION) { char *constructed_newloc; char *referer; referer=kstrdup(connection->u.url); /*DONE : handle relative urls too */ constructed_newloc = uri_merge(connection->u.url, connection->hs.newloc); proz_debug("Redirected to %s, merged URL = %s", connection->hs.newloc, constructed_newloc); proz_free_url(&connection->u, 0); connection->err = proz_parse_url(constructed_newloc, &connection->u, 0); if (connection->err != URLOK) { connection_show_message(connection, _ ("The server returned location is wrong: %s!"), constructed_newloc); pthread_mutex_lock(&connection->access_mutex); connection->running = FALSE; pthread_mutex_unlock(&connection->access_mutex); kfree(constructed_newloc); connection->err = HERR; return; } else connection_show_message(connection, _("Redirected to => %s"), constructed_newloc); connection->u.referer=referer; kfree(constructed_newloc); connection->err = NEWLOCATION; } } while (connection->err == NEWLOCATION); return;}void proz_connection_set_msg_proc(connection_t * connection, message_proc msg_proc, void *cb_data){ assert(connection != NULL); connection->msg_proc = msg_proc; connection->cb_data = cb_data;}void connection_calc_ratebps(connection_t * connection){ struct timeval tv_cur; struct timeval tv_diff; float diff_us; pthread_mutex_lock(&connection->access_mutex); if (connection->time_begin.tv_sec == 0 && connection->time_begin.tv_usec == 0) { connection->rate_bps = 0; pthread_mutex_unlock(&connection->access_mutex); return; } else { gettimeofday(&tv_cur, NULL); proz_timeval_subtract(&tv_diff, &tv_cur, &(connection->time_begin)); diff_us = ((float) tv_diff.tv_sec * 10e5) + tv_diff.tv_usec; if (diff_us == 0) { pthread_mutex_unlock(&connection->access_mutex); return; } connection->rate_bps = ((float) (connection->remote_bytes_received - (connection->remote_startpos-connection->orig_remote_startpos)) * 10e5 / diff_us); } pthread_mutex_unlock(&connection->access_mutex); return;}void connection_throttle_bps(connection_t * connection){ struct timeval tv_cur; struct timeval tv_diff; float diff_us; float wtime; struct timeval tv_delay; float con_timeout_usecs; pthread_mutex_lock(&connection->access_mutex); con_timeout_usecs = (connection->conn_timeout.tv_sec * 10e5) + connection->conn_timeout.tv_usec; if (connection->rate_bps == 0 || connection->max_allowed_bps == 0) { pthread_mutex_unlock(&connection->access_mutex); return; } if (connection->time_begin.tv_sec == 0 && connection->time_begin.tv_usec == 0) { pthread_mutex_unlock(&connection->access_mutex); return; } gettimeofday(&tv_cur, NULL); proz_timeval_subtract(&tv_diff, &tv_cur, &(connection->time_begin)); diff_us = ((float) tv_diff.tv_sec * 10e5) + tv_diff.tv_usec; if (diff_us == 0) { pthread_mutex_unlock(&connection->access_mutex); return; } wtime = 10e5 * connection->remote_bytes_received / connection->max_allowed_bps; pthread_mutex_unlock(&connection->access_mutex); memset(&tv_delay, 0, sizeof(tv_delay)); if (wtime > diff_us) { /*too fast have to delay */ if ((wtime - diff_us) > con_timeout_usecs) /* problem here */ { /*If we were to delay for wtime-diff_us we would cause a connection timeout, so rather than doing that shall we delay for a bit lesser than the time for the timeout, like say 1 second less */ const int limit_time_us = 2 * 10e5; /* Will the connection timeout - limit_time_us be less or equal to 0? If so no point in delaing beacuse the connection wold timeout */ if ((con_timeout_usecs - limit_time_us) <= 0) { proz_debug ("Cant throttle: Connection would timeout if done so, please try increasing the timeout value"); return; } tv_delay.tv_usec = con_timeout_usecs - limit_time_us; /* message ("Cant throttle fully : Connection would timeout if done so, please try increasing the timeout value"); */ proz_debug("delaymaxlimit %ld sec\n", tv_delay.tv_usec); } else { tv_delay.tv_usec = (wtime - diff_us);//#warning "comment out the following line before releasing the code base" proz_debug("sleeping %f secs\n", (wtime - diff_us) / 10e5); } tv_delay.tv_sec = tv_delay.tv_usec / 1000000; tv_delay.tv_usec = tv_delay.tv_usec % 1000000; if (select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv_delay) < 0) { proz_debug("Unable to throttle Bandwith\n"); } }}boolean proz_connection_running(connection_t * connection){ boolean running; pthread_mutex_lock(&connection->access_mutex); running = connection->running; pthread_mutex_unlock(&connection->access_mutex); return running;}void proz_connection_set_url(connection_t * connection, urlinfo *url){ assert(url); memcpy(&connection->u, proz_copy_url(url), sizeof(urlinfo));}void proz_connection_free_connection(connection_t * connection, boolean complete){ assert(connection); /*TODO what about szBuffer..also have to free the URL u */ if (connection->localfile) kfree(connection->localfile); if (connection->file_mode) kfree(connection->file_mode); if (connection->http_proxy) kfree(connection->http_proxy); if (connection->ftp_proxy) kfree(connection->ftp_proxy); if (connection->user_agent) kfree(connection->user_agent); /* free the serv_ret_lines array */ if (connection->serv_ret_lines != 0) { done_with_response(connection); } if (complete == TRUE) kfree(connection);}size_t write_data_with_lock(connection_t * connection, const void *ptr, size_t size, size_t nmemb){ size_t ret; flockfile(connection->fp); /*Seek appropriately......*/ ret=fseek(connection->fp, connection->local_startpos+connection->remote_bytes_received, SEEK_SET); ret=fwrite( ptr, size, nmemb, connection->fp); funlockfile(connection->fp); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -