/****************
创建URL请求连接
@url:url地址
创建好的请求放在全局变量request中
****************/
// 此函数主要目的是要把类似于http GET请求的信息全部存储到全局变量request[REQUEST_SIZE]
// 中,其中换行操作使用"\r\n"。其中应用了大量的字符串操作函数。
// 创建url请求连接,HTTP头,创建好的请求放在全局变量request中
void build_request(const char *url)
{
char tmp[10];
int i;
//请求地址和请求连接清零
bzero(host, MAXHOSTNAMELEN);
bzero(request, REQUEST_SIZE);
// 协议适配
if(force_reload && proxyhost!=NULL && http10 < 1) http10=1;
if(method==METHOD_HEAD && http10<1) http10=1;
if(method==METHOD_OPTIONS && http10<2) http10=2;
if(method==METHOD_TRACE && http10<2) http10=2;
switch(method)
{
default:
case METHOD_GET: strcpy(request,"GET");break;
case METHOD_HEAD: strcpy(request,"HEAD");break;
// 请求方法相应的不能缓存
case METHOD_OPTIONS: strcpy(request,"OPTIONS");break;
case METHOD_TRACE: strcpy(request,"TRACE");break;
}
// 追加空格
strcat(request, " ");
// strstr(str1, str2)用于判断str2是否是str1的子串
if(NULL == strstr(url,"://"))//找“://”在URL中的位置
{
fprintf(stderr, "\n%s: is not a valid URL.\n",url);
exit(2);
}
if(strlen(url)>1500)//url是否太长
{
fprintf(stderr, "URL is too long.\n");
exit(2);
}
if(proxyhost == NULL)//代理服务器是否为空
// 未使用代理服务器的情况下,只允许HTTP协议
if (0 != strncasecmp("http://", url, 7)) //比较前7个字符串
{
fprintf(stderr,"\nOnly HTTP protocol is directly supported, set --proxy for others.\n");
exit(2);
}
/* protocol/host delimiter */
i=strstr(url,"://")-url+3; //i指向http://后第一个字母
/* printf("%d\n",i); */
// URL后必须的'/'
if(strchr(url+i, '/') == NULL) {
fprintf(stderr, "\nInvalid URL syntax - hostname don't ends with '/'.\n");
exit(2);
}
// 如果未使用代理服务器,就表示肯定是HTTP协议
if(proxyhost == NULL)
{
/* get port from hostname */
// 如果是server:port形式,解析主机和端口
if(index(url+i, ':') != NULL &&
index(url+i, ':')<index(url+i, '/'))//判断url中是否指定了端口号
{
strncpy(host, url+i, strchr(url+i, ':')-url-i);//取出主机地址
bzero(tmp, 10);
strncpy(tmp, index(url+i,':')+1, strchr(url+i,'/')-index(url+i, ':')-1);
/* printf("tmp=%s\n",tmp); */
// 目标端口
proxyport = atoi(tmp);//端口号转换为int
if(proxyport == 0)
proxyport = 80;
}else
{
strncpy(host, url+i, strcspn(url+i, "/"));
}
// printf("Host=%s\n",host);
strcat(request+strlen(request), url+i+strcspn(url+i, "/"));
}else
{
// printf("ProxyHost=%s\nProxyPort=%d\n",proxyhost,proxyport);
/ 如若使用代理服务器
strcat(request, url);
}
if(http10 == 1)//版本号
strcat(request, " HTTP/1.0");
else if (http10 == 2)
strcat(request, " HTTP/1.1");
// 完成如 GET/HTTP1.1后,添加"\r\n"
strcat(request, "\r\n");
if(http10 > 0)
strcat(request, "User-Agent: WebBench "PROGRAM_VERSION"\r\n");
if(proxyhost == NULL && http10 > 0)
{
strcat(request, "Host: ");
strcat(request, host);
strcat(request, "\r\n");
}
// force_reload=1和存在代理服务器,则不缓存
if(force_reload && proxyhost != NULL)
{
strcat(request, "Pragma: no-cache\r\n");
}
// 如果为HTTP1.1,则存在长连接,应将Connection置位close
if(http10 > 1)
strcat(request, "Connection: close\r\n");
/* add empty line at end */
// 最后不要忘记在请求后添加“\r\n”
if(http10 > 0) strcat(request,"\r\n");
// printf("Req=%s\n",request);
}
创建URL请求连接
@url:url地址
创建好的请求放在全局变量request中
****************/
// 此函数主要目的是要把类似于http GET请求的信息全部存储到全局变量request[REQUEST_SIZE]
// 中,其中换行操作使用"\r\n"。其中应用了大量的字符串操作函数。
// 创建url请求连接,HTTP头,创建好的请求放在全局变量request中
void build_request(const char *url)
{
char tmp[10];
int i;
//请求地址和请求连接清零
bzero(host, MAXHOSTNAMELEN);
bzero(request, REQUEST_SIZE);
// 协议适配
if(force_reload && proxyhost!=NULL && http10 < 1) http10=1;
if(method==METHOD_HEAD && http10<1) http10=1;
if(method==METHOD_OPTIONS && http10<2) http10=2;
if(method==METHOD_TRACE && http10<2) http10=2;
switch(method)
{
default:
case METHOD_GET: strcpy(request,"GET");break;
case METHOD_HEAD: strcpy(request,"HEAD");break;
// 请求方法相应的不能缓存
case METHOD_OPTIONS: strcpy(request,"OPTIONS");break;
case METHOD_TRACE: strcpy(request,"TRACE");break;
}
// 追加空格
strcat(request, " ");
// strstr(str1, str2)用于判断str2是否是str1的子串
if(NULL == strstr(url,"://"))//找“://”在URL中的位置
{
fprintf(stderr, "\n%s: is not a valid URL.\n",url);
exit(2);
}
if(strlen(url)>1500)//url是否太长
{
fprintf(stderr, "URL is too long.\n");
exit(2);
}
if(proxyhost == NULL)//代理服务器是否为空
// 未使用代理服务器的情况下,只允许HTTP协议
if (0 != strncasecmp("http://", url, 7)) //比较前7个字符串
{
fprintf(stderr,"\nOnly HTTP protocol is directly supported, set --proxy for others.\n");
exit(2);
}
/* protocol/host delimiter */
i=strstr(url,"://")-url+3; //i指向http://后第一个字母
/* printf("%d\n",i); */
// URL后必须的'/'
if(strchr(url+i, '/') == NULL) {
fprintf(stderr, "\nInvalid URL syntax - hostname don't ends with '/'.\n");
exit(2);
}
// 如果未使用代理服务器,就表示肯定是HTTP协议
if(proxyhost == NULL)
{
/* get port from hostname */
// 如果是server:port形式,解析主机和端口
if(index(url+i, ':') != NULL &&
index(url+i, ':')<index(url+i, '/'))//判断url中是否指定了端口号
{
strncpy(host, url+i, strchr(url+i, ':')-url-i);//取出主机地址
bzero(tmp, 10);
strncpy(tmp, index(url+i,':')+1, strchr(url+i,'/')-index(url+i, ':')-1);
/* printf("tmp=%s\n",tmp); */
// 目标端口
proxyport = atoi(tmp);//端口号转换为int
if(proxyport == 0)
proxyport = 80;
}else
{
strncpy(host, url+i, strcspn(url+i, "/"));
}
// printf("Host=%s\n",host);
strcat(request+strlen(request), url+i+strcspn(url+i, "/"));
}else
{
// printf("ProxyHost=%s\nProxyPort=%d\n",proxyhost,proxyport);
/ 如若使用代理服务器
strcat(request, url);
}
if(http10 == 1)//版本号
strcat(request, " HTTP/1.0");
else if (http10 == 2)
strcat(request, " HTTP/1.1");
// 完成如 GET/HTTP1.1后,添加"\r\n"
strcat(request, "\r\n");
if(http10 > 0)
strcat(request, "User-Agent: WebBench "PROGRAM_VERSION"\r\n");
if(proxyhost == NULL && http10 > 0)
{
strcat(request, "Host: ");
strcat(request, host);
strcat(request, "\r\n");
}
// force_reload=1和存在代理服务器,则不缓存
if(force_reload && proxyhost != NULL)
{
strcat(request, "Pragma: no-cache\r\n");
}
// 如果为HTTP1.1,则存在长连接,应将Connection置位close
if(http10 > 1)
strcat(request, "Connection: close\r\n");
/* add empty line at end */
// 最后不要忘记在请求后添加“\r\n”
if(http10 > 0) strcat(request,"\r\n");
// printf("Req=%s\n",request);
}