不能通過代理訪問squid代理的網站
自己寫了一個http代理,測試的時候,發現不能通過代理訪問squid代理的網站。一般的網站都能訪問,比如本網站,但是有的網站根本就不能訪問,比如新浪。訪問搜狐也有一些鏈接不能打開,不知道為什麼?
訪問新浪
ERROR
The requested URL could not be retrieved
--------------------------------------------------------------------------------
While trying to retrieve the URL: http://news.sina.com.cn/
The following error was encountered:
Access Denied.
Access control configuration prevents your request from being allowed at this time. Please contact your service provider if you feel this is incorrect.
Your cache administrator is webmaster.
--------------------------------------------------------------------------------
Generated Wed, 28 Feb 2007 05:18:39 GMT by sh-35.sina.com.cn (CachePower/1.3.1.dev)
訪問搜狐的一個鏈接:
ERROR
The requested URL could not be retrieved
--------------------------------------------------------------------------------
While trying to retrieve the URL: http://photocdn.sohu.com/20070104/Img247425045.jpg
The following error was encountered:
Access Denied.
Access control configuration prevents your request from being allowed at this time. Please contact your service provider if you feel this is incorrect.
Your cache administrator is squid@chinacache.com. CHN-WX-1-341
--------------------------------------------------------------------------------
Generated Wed, 28 Feb 2007 05:18:56 GMT by CHN-WX-1-341 (ChinaCache SpeedUp China)
《解決方案》
這是我的源代碼(很簡單,不知道哪裡有問題)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <sys/types.h>
#include <pthread.h>
#ifdef WIN32
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <netdb.h>
#endif
#include "os.h"
#include "comm.h"
#ifdef WIN32
#define MAX_BUF 1024*10
#else
#define MAX_BUF 1024*1024
#endif
typedef struct proxyconn_st
{
char pname;
int sd;
}proxyconn;
int GetHttpDst(char *buf,char *ip,int *port,int *isconn)
{
char *HttpHead = "http://";
char *ConnHead = "HTTP/";
char *FirstLocation,*LastLocation,*PortLocation,*p;
char ServerName,PortString;
int NameLen;
printf("%s\n",buf);
*isconn=0;
if(strncmp(buf,"CONNECT",7)==0)
{
memset(ServerName,0,500);
p=strstr(buf,ConnHead);
memcpy(ServerName,buf+8,p-buf-8-1);
p=strstr(ServerName,":");
NameLen = p-ServerName;
memcpy(ip,ServerName,NameLen);
memset(PortString,0,10);
memcpy(PortString,p + 1,strlen(ServerName)-NameLen);
*port=atoi(PortString);
*isconn=1;
}
else
{
FirstLocation = strstr(buf,HttpHead) + strlen(HttpHead);
LastLocation = strstr(FirstLocation,"/");
memset(ServerName,0,500);
memcpy(ServerName,FirstLocation,LastLocation - FirstLocation);
PortLocation = strstr(ServerName,":");
if(PortLocation != NULL)
{
NameLen = PortLocation - ServerName ;
memcpy(ip,ServerName,NameLen);
memset(PortString,0,10);
memcpy(PortString,PortLocation + 1,strlen(ServerName)-NameLen);
*port=atoi(PortString);
}
else
{
strcpy(ip,ServerName);
*port=80;
}
}
return 0;
}
int GetDst(char *pname,char *buf,char *ip,int *port,int *isconn)
{
int ret;
if(!strcmp(pname,"http"))
{
ret=GetHttpDst(buf,ip,port,isconn);
if(ret!=0)
{
printf("GetHttpDst err\n");
return -1;
}
}
return 0;
}
int ConnectDst(char *host,int port , int *sock)
{
int optlen,s,ret;
struct linger linger;
struct sockaddr_in dest;
struct hostent *hst;
linger.l_onoff = 1;
linger.l_linger = 2;
optlen = sizeof(linger) ;
s = socket(AF_INET, SOCK_STREAM, 0);
if(s<0)
{
printf("socket err\n");
return -1;
}
if(setsockopt(s, SOL_SOCKET, SO_LINGER, (char*)&linger, optlen) != 0)
{
return -1;
}
hst=gethostbyname(host);
if(hst==NULL)
{
printf("get host by name err\n");
return -1;
}
dest.sin_family = AF_INET;
dest.sin_addr=*((struct in_addr *)hst->h_addr);
dest.sin_port = htons(port);
ret=connect(s,(struct sockaddr*) &dest, sizeof( dest));
if(ret<0)
{
return -1;
}
*sock=s;
printf("connect %s ok\n",host);
return 0;
}
static void * thread_main(void *arg)
{
int ret,len;
int sd,sock;
char buf,ip;
int port;
int mx,isconn=0;
proxyconn *a;
a=(proxyconn *)arg;
sd=a->sd;
while(1)
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(sd,&fds);
ret=select(sd+1,&fds,NULL,NULL,NULL);
if(ret<=0)
{
printf("select out\n");
break;
}
if(FD_ISSET(sd,&fds))
{
/* read from client */
memset(buf,0,MAX_BUF);
len=recv(sd,buf,MAX_BUF,0);
if(len<=0)
{
closesocket(sd);
return 0;
}
/* send to server */
memset(ip,0,100);
ret=GetDst(a->pname,buf,ip,&port,&isconn);
ret=ConnectDst(ip,port,&sock);
if(ret!=0)
{
printf("conn dst err\n");
closesocket(sd);
return NULL;
}
/* added later for CONNECTION METHOD */
if(isconn==1)
{
memset(buf,0,MAX_BUF);
strcpy(buf,"HTTP/1.0 200 Connection established\nProxy-agent: Netscape-Proxy/1.1\n");
len=send(sd,buf,strlen(buf),0);
}
else
{
/* send to server */
len=send(sock,buf,len,0);
if(len<=0)
{
closesocket(sd);
closesocket(sock);
return 0;
}
}
if(sock>sd)
mx=sock;
else
mx=sd;
}
while(1)
{
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(sd,&readfds);
FD_SET(sock,&readfds);
ret=select(mx+1,&readfds,NULL,NULL,NULL); /* user control */
if(ret<=0)
{
closesocket(sd);
closesocket(sock);
return 0;
}
if(FD_ISSET(sd,&readfds))
{
/* read from client */
memset(buf,0,MAX_BUF);
len=recv(sd,buf,MAX_BUF,0);
if(len<=0)
{
closesocket(sd);
closesocket(sock);
return 0;
}
// printf("%s\n",buf);
/* send to server */
len=send(sock,buf,len,0);
if(len<=0)
{
closesocket(sd);
closesocket(sock);
return 0;
}
}
if(FD_ISSET(sock,&readfds))
{
/* read from server */
memset(buf,0,MAX_BUF);
len=recv(sock,buf,MAX_BUF,0);
if(len<=0)
{
closesocket(sd);
closesocket(sock);
return 0;
}
printf("server :\n%s\n",buf);
/* send to client */
len=send(sd,buf,len,0);
if(len<=0)
{
closesocket(sd);
closesocket(sock);
return 0;
}
}
}
}
closesocket(sd);
closesocket(sock);
return 0;
}
#ifdef APP
int main()
#else
int proxyServer(char *name,int port)
#endif
{
int s,sd,ret,one=1;
struct sockaddr_in service;
pthread_t pid;
proxyconn cn;
#ifdef APP
char name;
strcpy(name,"http");
#endif
SysInit();
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(s<0)
{
printf("socket err\n");
return -1;
}
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) < 0)
{
printf("Error: Cannot set SO_REUSEADDR option!\n");
return -1;
}
service.sin_family = AF_INET;
service.sin_addr.s_addr = htonl(INADDR_ANY);
#ifdef APP
service.sin_port = htons(808);
#else
service.sin_port = htons(port);
#endif
if (bind( s, (struct sockaddr*) &service, sizeof(service)) <0)
{
printf("bind() failed.\n");
closesocket(s);
return -1;
}
if (listen( s, 5) <0)
{
printf("listen err\n");
return -1;
}
while(1)
{
struct timeval tv;
fd_set fdset;
tv.tv_sec = 1;
tv.tv_usec = 0;
FD_ZERO(&fdset);
FD_SET(s, &fdset);
ret=select(s+1, &fdset, NULL, NULL, NULL);
if(ret<=0)
continue;
if(FD_ISSET(s, &fdset))
{
sd=accept(s, NULL,NULL);
if(sd>0)
{
cn.sd=sd;
strcpy(cn.pname,name);
ret=pthread_create(&pid,NULL,&thread_main,(void *)&cn);
pthread_detach(pid);
}
}
}
SysFinal();
return 0;
}