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

📄 url.c

📁 harvest是一个下载html网页得机器人
💻 C
📖 第 1 页 / 共 5 页
字号:
  Curl_safefree(conn->allocptr.uagent);  Curl_safefree(conn->allocptr.userpwd);  Curl_safefree(conn->allocptr.accept_encoding);  Curl_safefree(conn->allocptr.rangeline);  Curl_safefree(conn->allocptr.ref);  Curl_safefree(conn->allocptr.cookie);  Curl_safefree(conn->allocptr.host);  Curl_safefree(conn->allocptr.cookiehost);  Curl_safefree(conn->proxyhost);#ifdef USE_ARES  /* possible left-overs from the async name resolve */  Curl_safefree(conn->async.hostname);#endif    Curl_free_ssl_config(&conn->ssl_config);  free(conn); /* free all the connection oriented data */  return CURLE_OK;}/* * This function should return TRUE if the socket is to be assumed to * be dead. Most commonly this happens when the server has closed the * connection due to inactivity. */static bool SocketIsDead(int sock){  int sval;  bool ret_val = TRUE;  fd_set check_set;  struct timeval to;  FD_ZERO(&check_set);  FD_SET(sock,&check_set);  to.tv_sec = 0;  to.tv_usec = 0;  sval = select(sock + 1, &check_set, 0, 0, &to);  if(sval == 0)    /* timeout */    ret_val = FALSE;  return ret_val;}/* * Given one filled in connection struct (named needle), this function should * detect if there already is one that have all the significant details * exactly the same and thus should be used instead. */static boolConnectionExists(struct SessionHandle *data,                 struct connectdata *needle,                 struct connectdata **usethis){  long i;  struct connectdata *check;  for(i=0; i< data->state.numconnects; i++) {    bool match = FALSE;    /*     * Note that if we use a HTTP proxy, we check connections to that     * proxy and not to the actual remote server.     */    check = data->state.connects[i];    if(!check)      /* NULL pointer means not filled-in entry */      continue;    if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL))      /* don't do mixed SSL and non-SSL connections */      continue;    if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) {      /* The requested connection does not use a HTTP proxy or it         uses SSL. */      if(!(needle->protocol&PROT_SSL) && check->bits.httpproxy)        /* we don't do SSL but the cached connection has a proxy,           then don't match this */        continue;      if(strequal(needle->protostr, check->protostr) &&         strequal(needle->name, check->name) &&         (needle->remote_port == check->remote_port) ) {        if(needle->protocol & PROT_SSL) {          /* This is SSL, verify that we're using the same             ssl options as well */          if(!Curl_ssl_config_matches(&needle->ssl_config,                                      &check->ssl_config)) {            continue;          }        }        if((needle->protocol & PROT_FTP) ||           ((needle->protocol & PROT_HTTP) &&            (needle->data->state.authwant==CURLAUTH_NTLM))) {          /* This is FTP or HTTP+NTLM, verify that we're using the same name             and password as well */          if(!strequal(needle->user, check->user) ||             !strequal(needle->passwd, check->passwd)) {            /* one of them was different */            continue;          }        }        match = TRUE;      }    }    else { /* The requested needle connection is using a proxy,              is the checked one using the same? */      if(check->bits.httpproxy &&         strequal(needle->proxyhost, check->proxyhost) &&         needle->port == check->port) {        /* This is the same proxy connection, use it! */        match = TRUE;      }    }    if(match) {      bool dead = SocketIsDead(check->firstsocket);      if(dead) {        /*         */        infof(data, "Connection %d seems to be dead!\n", i);        Curl_disconnect(check); /* disconnect resources */        data->state.connects[i]=NULL; /* nothing here */        /* There's no need to continue searching, because we only store           one connection for each unique set of identifiers */        return FALSE;      }      *usethis = check;      return TRUE; /* yes, we found one to use! */    }  }  return FALSE; /* no matching connecting exists */}/* * This function frees/closes a connection in the connection cache. This * should take the previously set policy into account when deciding which * of the connections to kill. */static intConnectionKillOne(struct SessionHandle *data){  long i;  struct connectdata *conn;  int highscore=-1;  int connindex=-1;  int score;  CURLcode result;  struct timeval now;  now = Curl_tvnow();  for(i=0; i< data->state.numconnects; i++) {    conn = data->state.connects[i];    if(!conn)      continue;    /*     * By using the set policy, we score each connection.     */    switch(data->set.closepolicy) {    case CURLCLOSEPOLICY_LEAST_RECENTLY_USED:    default:      /*       * Set higher score for the age passed since the connection       * was used.       */      score = Curl_tvdiff(now, conn->now);      break;    case CURLCLOSEPOLICY_OLDEST:      /*       * Set higher score for the age passed since the connection       * was created.       */      score = Curl_tvdiff(now, conn->created);      break;    }    if(score > highscore) {      highscore = score;      connindex = i;    }  }  if(connindex >= 0) {    /* the winner gets the honour of being disconnected */    result = Curl_disconnect(data->state.connects[connindex]);    /* clean the array entry */    data->state.connects[connindex] = NULL;  }  return connindex; /* return the available index or -1 */}/* * The given input connection struct pointer is to be stored. If the "cache" * is already full, we must clean out the most suitable using the previously * set policy. * * The given connection should be unique. That must've been checked prior to * this call. */static unsigned intConnectionStore(struct SessionHandle *data,                struct connectdata *conn){  long i;  for(i=0; i< data->state.numconnects; i++) {    if(!data->state.connects[i])      break;  }  if(i == data->state.numconnects) {    /* there was no room available, kill one */    i = ConnectionKillOne(data);    infof(data, "Connection (#%d) was killed to make room\n", i);  }  if(-1 != i) {    /* only do this if a true index was returned, if -1 was returned there       is no room in the cache for an unknown reason and we cannot store       this there. */    data->state.connects[i] = conn; /* fill in this */    conn->connectindex = i; /* make the child know where the pointer to this                               particular data is stored */  }  return i;}/* * This function logs in to a SOCKS5 proxy and sends the specifies the final * desitination server. */static int handleSock5Proxy(    const char *proxy_name,    const char *proxy_password,    struct connectdata *conn,    int sock){  unsigned char socksreq[600]; /* room for large user/pw (255 max each) */  ssize_t actualread;  ssize_t written;  CURLcode result;  Curl_nonblock(sock, FALSE);  socksreq[0] = 5; /* version */  socksreq[1] = (char)(proxy_name[0] ? 2 : 1); /* number of methods (below) */  socksreq[2] = 0; /* no authentication */  socksreq[3] = 2; /* username/password */  result = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),                      &written);  if ((result != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {    failf(conn->data, "Unable to send initial SOCKS5 request.");    return 1;  }  result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);  if ((result != CURLE_OK) || (actualread != 2)) {    failf(conn->data, "Unable to receive initial SOCKS5 response.");    return 1;  }  if (socksreq[0] != 5) {    failf(conn->data, "Received invalid version in initial SOCKS5 response.");    return 1;  }  if (socksreq[1] == 0) {    /* Nothing to do, no authentication needed */    ;  }  else if (socksreq[1] == 2) {    /* Needs user name and password */    int userlen, pwlen, len;    userlen = strlen(proxy_name);    pwlen = strlen(proxy_password);    /*   username/password request looks like     * +----+------+----------+------+----------+     * |VER | ULEN |  UNAME   | PLEN |  PASSWD  |     * +----+------+----------+------+----------+     * | 1  |  1   | 1 to 255 |  1   | 1 to 255 |     * +----+------+----------+------+----------+     */    len = 0;    socksreq[len++] = 1;    /* username/pw subnegotiation version */    socksreq[len++] = (char) userlen;    memcpy(socksreq + len, proxy_name, (int) userlen);    len += userlen;    socksreq[len++] = (char) pwlen;    memcpy(socksreq + len, proxy_password, (int) pwlen);    len += pwlen;    result = Curl_write(conn, sock, (char *)socksreq, len, &written);    if ((result != CURLE_OK) || (len != written)) {      failf(conn->data, "Failed to send SOCKS5 sub-negotiation request.");      return 1;    }    result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);    if ((result != CURLE_OK) || (actualread != 2)) {      failf(conn->data, "Unable to receive SOCKS5 sub-negotiation response.");      return 1;    }    if ((socksreq[0] != 1) || /* version */        (socksreq[1] != 0)) { /* status */      failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",            socksreq[0], socksreq[1]);      return 1;    }    /* Everything is good so far, user was authenticated! */  }  else {    /* error */    if (socksreq[1] == 1) {      failf(conn->data,            "SOCKS5 GSSAPI per-message authentication is not supported.");      return 1;    }    else if (socksreq[1] == 255) {      if (proxy_name[0] == 0) {        failf(conn->data,              "No authentication method was acceptable. (It is quite likely"              " that the SOCKS5 server wanted a username/password, since none"              " was supplied to the server on this connection.)");      }      else {        failf(conn->data, "No authentication method was acceptable.");      }      return 1;    }    else {      failf(conn->data,            "Undocumented SOCKS5 mode attempted to be used by server.");      return 1;    }  }  /* Authentication is complete, now specify destination to the proxy */  socksreq[0] = 5; /* version (SOCKS5) */  socksreq[1] = 1; /* connect */  socksreq[2] = 0; /* must be zero */  socksreq[3] = 1; /* IPv4 = 1 */  {#ifndef ENABLE_IPV6    struct Curl_dns_entry *dns;    Curl_addrinfo *hp=NULL;    int rc = Curl_resolv(conn, conn->hostname, conn->remote_port, &dns);        if(rc == -1)      return CURLE_COULDNT_RESOLVE_HOST;    if(rc == 1)      /* this requires that we're in "wait for resolve" state */      rc = Curl_wait_for_resolv(conn, &dns);        /*     * We cannot use 'hostent' as a struct that Curl_resolv() returns.  It     * returns a Curl_addrinfo pointer that may not always look the same.     */    if(dns)      hp=dns->addr;    if (hp && hp->h_addr_list[0]) {      socksreq[4] = ((char*)hp->h_addr_list[0])[0];      socksreq[5] = ((char*)hp->h_addr_list[0])[1];      socksreq[6] = ((char*)hp->h_addr_list[0])[2];      socksreq[7] = ((char*)hp->h_addr_list[0])[3];      Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */    }    else {      failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.",            conn->hostname);      return 1;    }#else    failf(conn->data,          "%s:%d has an internal error an needs to be fixed to work",          __FILE__, __LINE__);    return 1;#endif  }  *((unsigned short*)&socksreq[8]) = htons(conn->remote_port);  {    const int packetsize = 10;    result = Curl_write(conn, sock, (char *)socksreq, packetsize, &written);    if ((result != CURLE_OK) || (written != packetsize)) {      failf(conn->data, "Failed to send SOCKS5 connect request.");      return 1;    }    result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread);    if ((result != CURLE_OK) || (actualread != packetsize)) {      failf(conn->data, "Failed to receive SOCKS5 connect request ack.");      return 1;    }    if (socksreq[0] != 5) { /* version */      failf(conn->data,            "SOCKS5 reply has wrong version, version should be 5.");      return 1;    }    if (socksreq[1] != 0) { /* Anything besides 0 is an error */        failf(conn->data,              "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",              (unsigned char)socksreq[4], (unsigned char)socksreq[5],              (unsigned char)socksreq[6], (unsigned char)socksreq[7],              (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),              socksreq[1]);        return 1;    }  }  Curl_nonblock(sock, TRUE);  return 0; /* Proxy was successful! */}static CURLcode ConnectPlease(struct connectdata *conn,                              struct Curl_dns_entry *hostaddr,                              bool *connected)

⌨️ 快捷键说明

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