⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 http.c

📁 prozgui是一款Linxu下著名的下载工具
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* If the server specified a new location then lets store it. */    if (!hs->newloc)      hs->newloc = hgetlocation(hdr);    if (!hs->remote_time)      hs->remote_time = hgetmodified(hdr);    if (hs->accept_ranges == -1)      hs->accept_ranges = hgetaccept_ranges(hdr);    if (!hs->newloc)      hs->newloc = hgetlocation(hdr);    kfree(hdr);  }  if (H_20X(statcode))    return HOK;  if (H_REDIRECTED(statcode) || statcode == HTTP_MULTIPLE_CHOICES)  {    /* RFC2068 says that in case of the 300 (multiple choices) response, the       server can output a preferred URL through `Location' header; otherwise,       the request should be treated like GET. So, if the location is set, it       will be a redirection; otherwise, just proceed normally. */    if (statcode == HTTP_MULTIPLE_CHOICES && !hs->newloc)      return HOK;    else    {      if (all_headers)	kfree(all_headers);      if (type)	kfree(type);      return NEWLOCATION;    }  }  if (statcode == HTTP_UNAUTHORIZED)    return HAUTHREQ;  if (statcode == HTTP_NOT_FOUND)    return HTTPNSFOD;  if (statcode == HTTP_INTERNAL)    return INTERNALSERVERR;  if (statcode == HTTP_NOT_IMPLEMENTED)    return UNKNOWNREQ;  if (statcode == HTTP_BAD_GATEWAY)    return BADGATEWAY;  if (statcode == HTTP_UNAVAILABLE)    return SERVICEUNAVAIL;  if (statcode == HTTP_GATEWAY_TIMEOUT)    return GATEWAYTIMEOUT;  return HERR;}/****************************************************************************** ...******************************************************************************/char *get_basic_auth_str(char *user, char *passwd, char *auth_header){  char *p1, *p2, *ret;  int len = strlen(user) + strlen(passwd) + 1;  int b64len = 4 * ((len + 2) / 3);  p1 = kmalloc(len + 1);  sprintf(p1, "%s:%s", user, passwd);  p2 = kmalloc(b64len + 1);  /* Encode username:passwd to base64. */  base64_encode(p1, p2, len);  ret = kmalloc(strlen(auth_header) + b64len + 11);  sprintf(ret, "%s: Basic %s\r\n", auth_header, p2);  kfree(p1);  kfree(p2);  return ret;}/****************************************************************************** ...******************************************************************************/boolean http_use_proxy(connection_t * connection){  return (connection->http_proxy && connection->http_proxy->use_proxy	  && connection->http_proxy->proxy_url.url) ? TRUE : FALSE;}/****************************************************************************** ...******************************************************************************/uerr_t proz_http_get_url_info(connection_t * connection){  uerr_t err;  int remote_port_len;  char *user, *passwd, *www_auth = NULL, *proxy_auth = NULL,      *referer = NULL, *location = NULL, *pragma_no_cache = NULL;  char *request, *remote_port;  netrc_entry *netrc_ent;  memset(&connection->hs, 0, sizeof(connection->hs));  if (http_use_proxy(connection))  {    connection_show_message(connection, _("Connecting to %s"),			    connection->http_proxy->proxy_url.host);    err = connect_to_server(&connection->data_sock,			    connection->http_proxy->proxy_url.host,			    connection->http_proxy->proxy_url.port,			    &connection->xfer_timeout);    if (err != NOCONERROR)    {      connection_show_message(connection, _("Error connecting to %s"),			      connection->http_proxy->proxy_url.host);      return err;    }  } else  {    connection_show_message(connection, _("Connecting to %s"),			    connection->u.host);    err = connect_to_server(&connection->data_sock, connection->u.host,			    connection->u.port, &connection->xfer_timeout);    if (err != NOCONERROR)    {      connection_show_message(connection, _("Error connecting to %s"),			      connection->u.host);      return err;    }  }  user = connection->u.user;  passwd = connection->u.passwd;  /* Use .netrc if asked to do so. */  if (connection->use_netrc == TRUE)  {    netrc_ent = search_netrc(libprozrtinfo.netrc_list, connection->u.host);    if (netrc_ent != NULL)    {      user = netrc_ent->account;      passwd = netrc_ent->password;    }  }  user = user ? user : "";  passwd = passwd ? passwd : "";  if (strlen(user) || strlen(passwd))  {    /* Construct the necessary header. */    www_auth = get_basic_auth_str(user, passwd, "Authorization");    proz_debug(_("Authenticating as user %s password %s"), user, passwd);    proz_debug(_("Authentification string=%s"), www_auth);  } else    www_auth = 0;  if (http_use_proxy(connection))  {    if (strlen(connection->http_proxy->username)	|| strlen(connection->http_proxy->passwd))      proxy_auth =	  get_basic_auth_str(connection->http_proxy->username,			     connection->http_proxy->passwd,			     "Proxy-Authorization");  }  if (connection->u.port == 80)  {    remote_port = NULL;    remote_port_len = 0;  } else  {    remote_port = (char *) alloca(64);    remote_port_len = sprintf(remote_port, ":%d", connection->u.port);  }  if (connection->u.referer)  {    referer = (char *) alloca(13 + strlen(connection->u.referer));    sprintf(referer, "Referer: %s\r\n", connection->u.referer);  }  /* If we go through a proxy the request for the URL is different */  if (http_use_proxy(connection))  {    location = (char *) alloca(strlen(connection->u.url) + 1);    strcpy(location, connection->u.url);  } else  {    location = (char *) alloca(strlen(connection->u.path) + 1);    strcpy(location, connection->u.path);  }  /*Use no-cache directive for proxy servers? */  if (http_use_proxy(connection)      && (connection->http_no_cache || connection->attempts > 0))  {    pragma_no_cache = (char *) alloca(21);    sprintf(pragma_no_cache, "Pragma: no-cache\r\n");  }  request = (char *) alloca(strlen(location)			    + strlen(connection->user_agent)			    + strlen(connection->u.host) + remote_port_len			    + (referer ? strlen(referer) : 0)			    + (www_auth ? strlen(www_auth) : 0)			    + (proxy_auth ? strlen(proxy_auth) : 0) + 64			    +			    (pragma_no_cache ? strlen(pragma_no_cache) :			     0));  sprintf(request,	  "GET %s HTTP/1.0\r\nUser-Agent: %s\r\nHost: %s%s\r\nAccept: */*\r\n%s%s%s%s\r\n",	  location, connection->user_agent, connection->u.host,	  remote_port ? remote_port : "",	  referer ? referer : "",	  www_auth ? www_auth : "", proxy_auth ? proxy_auth : "",	  pragma_no_cache ? pragma_no_cache : "");  proz_debug("HTTP request = %s", request);  connection_show_message(connection, _("Sending HTTP request"));  err = http_fetch_headers(connection, &connection->hs, request);  close_sock(&connection->data_sock);  if (err == HOK)  {    connection->main_file_size = connection->hs.contlen;    if (connection->hs.accept_ranges == 1)      connection->resume_support = TRUE;    else if (connection->hs.accept_ranges == -1)      connection->resume_support = FALSE;  }  connection->file_type = REGULAR_FILE;  return err;}/*Loops for connection->attempts */uerr_t http_get_url_info_loop(connection_t * connection){  pthread_mutex_lock(&connection->access_mutex);  connection->running = TRUE;  pthread_mutex_unlock(&connection->access_mutex);  assert(connection->attempts >= 0);  do  {    if (connection->attempts > 0 && connection->err != NEWLOCATION)    {      connection_show_message(connection,			      _("Retrying...Attempt %d in %d seconds"),			      connection->attempts,			      connection->retry_delay.tv_sec);      delay_ms(connection->retry_delay.tv_sec * 1000);    }    /*Push the handler which will cleanup any sockets that are left open */    pthread_cleanup_push(cleanup_socks, (void *) connection);    connection->err = proz_http_get_url_info(connection);    /*pop the handler */    pthread_cleanup_pop(0);    connection->attempts++;    switch (connection->err)    {    case HOK:      connection_show_message(connection, _("Successfully got info"));      pthread_mutex_lock(&connection->access_mutex);      connection->running = FALSE;      pthread_mutex_unlock(&connection->access_mutex);      return connection->err;      break;    case NEWLOCATION:      return connection->err;      break;    case HTTPNSFOD:      connection_show_message(connection, _("File not found!"));      pthread_mutex_lock(&connection->access_mutex);      connection->running = FALSE;      pthread_mutex_unlock(&connection->access_mutex);      return connection->err;      break;    default:      connection_show_message(connection, proz_strerror(connection->err));      break;    }  }  while ((connection->attempts < connection->max_attempts)	 || connection->max_attempts == 0);  connection_show_message(connection,			  _			  ("I have tried %d attempt(s) and have failed, aborting"),			  connection->attempts);  pthread_mutex_lock(&connection->access_mutex);  connection->running = FALSE;  pthread_mutex_unlock(&connection->access_mutex);  return connection->err;}/*  I am writing a seperate function to handle FTP proxying through HTTP, I  MHO whoever thought of using HTTP to proxy FTP is a shithead,   its such a PITA ;) */uerr_t ftp_get_url_info_from_http_proxy(connection_t * connection){  uerr_t err;  int remote_port_len;  char *user, *passwd, *www_auth = NULL, *proxy_auth =      NULL, *pragma_no_cache = NULL;  char *request, *remote_port;  netrc_entry *netrc_ent;  memset(&connection->hs, 0, sizeof(connection->hs));  err = connect_to_server(&connection->data_sock,			  connection->ftp_proxy->proxy_url.host,			  connection->ftp_proxy->proxy_url.port,			  &connection->xfer_timeout);  if (err != NOCONERROR)  {    connection_show_message(connection, _("Error connecting to %s"),			    connection->ftp_proxy->proxy_url.host);    return err;  }  user = connection->u.user;  passwd = connection->u.passwd;  /* Use .netrc if asked to do so. */  if (connection->use_netrc == TRUE)  {    netrc_ent = search_netrc(libprozrtinfo.netrc_list, connection->u.host);    if (netrc_ent != NULL)    {      user = netrc_ent->account;      passwd = netrc_ent->password;    }  }  user = user ? user : "";  passwd = passwd ? passwd : "";  if (strlen(user) || strlen(passwd))  {    /* Construct the necessary header. */    www_auth = get_basic_auth_str(user, passwd, "Authorization");    proz_debug(_("Authenticating as user %s password %s"), user, passwd);    proz_debug(_("Authentification string=%s"), www_auth);  } else    www_auth = 0;  if (strlen(connection->ftp_proxy->username)      || strlen(connection->ftp_proxy->passwd))    proxy_auth =	get_basic_auth_str(connection->ftp_proxy->username,			   connection->ftp_proxy->passwd,			   "Proxy-Authorization");  remote_port = (char *) alloca(64);  remote_port_len = sprintf(remote_port, ":%d", connection->u.port);  if (http_use_proxy(connection)      && (connection->http_no_cache || connection->attempts > 0))  {    pragma_no_cache = (char *) alloca(21);    sprintf(pragma_no_cache, "Pragma: no-cache\r\n");  }  /*Referrer TAG should not be needed in FTP through HTTP proxy..right */  request = (char *) alloca(strlen(connection->u.url)			    + strlen(connection->user_agent)			    + strlen(connection->u.host) + remote_port_len			    + (www_auth ? strlen(www_auth) : 0)			    + (proxy_auth ? strlen(proxy_auth) : 0)			    + 64			    +			    (pragma_no_cache ? strlen(pragma_no_cache) :			     0));  sprintf(request,	  "GET %s HTTP/1.0\r\nUser-Agent: %s\r\nHost: %s%s\r\nAccept: */*\r\n%s%s%s\r\n",	  connection->u.url, connection->user_agent, connection->u.host,	  remote_port,	  www_auth ? www_auth : "", proxy_auth ? proxy_auth : "",	  pragma_no_cache ? pragma_no_cache : "");  proz_debug("HTTP request = %s", request);  err = http_fetch_headers(connection, &connection->hs, request);  close_sock(&connection->data_sock);  /*Convert the error code to the equivalent FTP one if possible */  if (err == HOK)  {    connection->main_file_size = connection->hs.contlen;    if (connection->hs.accept_ranges == 1)      connection->resume_support = TRUE;    else if (connection->hs.accept_ranges == -1)      connection->resume_support = FALSE;    return FTPOK;  }  if (err == HAUTHREQ)    return FTPLOGREFUSED;  else if (err == HTTPNSFOD)    return FTPNSFOD;  /*  connection->file_type = REGULAR_FILE; */  return FTPERR;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -