webbench源碼分析之build_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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章