📄 http.cpp
字号:
if( iPage.m_sContentType.find("image") != string::npos ){ // close(sock); *nPSock = -1; return -4; } // paragraph end if (iPage.m_nContentLength == -1) { close(sock); *nPSock = -1; cout << headerBuf << endl; cout << "!error: Content-length" << endl; return -1; } if (iPage.m_nContentLength==0 || iPage.m_nContentLength<20) { // Allocate enough memory to hold the page iPage.m_nContentLength = DEFAULT_PAGE_BUF_SIZE; } if (iPage.m_nContentLength > MAX_PAGE_BUF_SIZE) { cout << "the page discarded due to its size " << iPage.m_nContentLength << " is larger than " << MAX_PAGE_BUF_SIZE << endl; close(sock); *nPSock = -1; return -1; } #ifdef DEBUG // http content length cout <<"######Content length: ######" << endl << iPage.m_nContentLength << endl; #endif //pthread_mutex_lock(&mutexMemory); pageBuf = (char *)malloc(iPage.m_nContentLength); //pthread_mutex_unlock(&mutexMemory); if(pageBuf == NULL){ close(sock); *nPSock = -1; cout << "malloc for pageBuf" << endl; return -1; } /* Begin reading the body of the file */ fd_set rfds; struct timeval tv; int flags; flags=fcntl(sock,F_GETFL,0); if(flags<0){ close(sock); *nPSock = -1; if (pageBuf) { //pthread_mutex_lock(&mutexMemory); free(pageBuf); pageBuf=NULL; //pthread_mutex_unlock(&mutexMemory); } cout << "1.fcntl() error " << endl; return -1; } flags|=O_NONBLOCK; if(fcntl(sock,F_SETFL,flags)<0){ close(sock); *nPSock = -1; if (pageBuf) { free(pageBuf); pageBuf=NULL; } cout << "2.fcntl() error " << endl; return -1; } int pre_ret=0; while(ret > 0){ FD_ZERO(&rfds); FD_SET(sock, &rfds); if( bytesRead == iPage.m_nContentLength ){ tv.tv_sec = 1; }else{ tv.tv_sec = timeout; } tv.tv_usec = 0; if(DEFAULT_TIMEOUT >= 0) selectRet = select(sock+1, &rfds, NULL, NULL, &tv); else /* No timeout, can block indefinately */ selectRet = select(sock+1, &rfds, NULL, NULL, NULL); if(selectRet == 0 && timeout < 0){ close(sock); *nPSock = -1; if (pageBuf) { //pthread_mutex_lock(&mutexMemory); free(pageBuf); pageBuf=NULL; //pthread_mutex_unlock(&mutexMemory); } cout << "selectRet == 0 && timeout < 0" << endl; return -1; } else if(selectRet == -1){ close(sock); *nPSock = -1; if (pageBuf) { //pthread_mutex_lock(&mutexMemory); free(pageBuf); pageBuf=NULL; //pthread_mutex_unlock(&mutexMemory); } cout << "selectRet == -1" << endl; return -1; } ret = read(sock, pageBuf + bytesRead, iPage.m_nContentLength); //ret = read(sock, (char*)pageBuf.c_str() + bytesRead, iPage.m_nContentLength); if(ret == 0) break; if(ret == -1 && pre_ret==0) { close(sock); *nPSock = -1; if (pageBuf) { //pthread_mutex_lock(&mutexMemory); free(pageBuf); pageBuf=NULL; //pthread_mutex_unlock(&mutexMemory); } cout << "read()'s retval=-1" << endl; return -1; }else if( ret == -1 && pre_ret ){ //cout << "2. pre_ret = " << pre_ret << endl;/* if( bytesRead < iPage.m_nContentLength){ // meaning we lost the connection too soon cout << "lost the connection too soon" << endl; freeOpageBuf); return -1; }*/ break; } pre_ret = ret; //cout << "1.pre_ret = " << pre_ret << endl; bytesRead += ret; /* To be tolerant of inaccurate Content-Length fields, we'll * allocate another read-sized chunk to make sure we have * enough room. */ if(ret > 0) { //pthread_mutex_lock(&mutexMemory); pageBuf = (char *)realloc(pageBuf, bytesRead + iPage.m_nContentLength); //pthread_mutex_unlock(&mutexMemory); if(pageBuf == NULL) { close(sock); *nPSock = -1; if (pageBuf) { //pthread_mutex_lock(&mutexMemory); free(pageBuf); pageBuf=NULL; //pthread_mutex_unlock(&mutexMemory); } cout << "realloc()" << endl; return -1; } } } /* * The download buffer is too large. Trim off the safety padding. */ //pthread_mutex_lock(&mutexMemory); pageBuf = (char *)realloc(pageBuf, bytesRead+1); //pthread_mutex_unlock(&mutexMemory); if(pageBuf == NULL){ close(sock); *nPSock = -1; if (pageBuf) { //pthread_mutex_lock(&mutexMemory); free(pageBuf); pageBuf=NULL; //pthread_mutex_unlock(&mutexMemory); } cout << "2.realloc()" << endl; return -1; } pageBuf[bytesRead] = '\0'; if(fileBuf == NULL){ /* They just wanted us to "hit" the url */ if (pageBuf) { //pthread_mutex_lock(&mutexMemory); free(pageBuf); pageBuf=NULL; //pthread_mutex_unlock(&mutexMemory); } }else{ char *tmp; //tmp = (char *)malloc(HEADER_BUF_SIZE); //pthread_mutex_lock(&mutexMemory); tmp = (char *)malloc(strlen(headerBuf)+1); //pthread_mutex_unlock(&mutexMemory); if(tmp == NULL){ close(sock); *nPSock = -1; if (pageBuf) { //pthread_mutex_lock(&mutexMemory); free(pageBuf); pageBuf=NULL; //pthread_mutex_unlock(&mutexMemory); } cout << "malloc() for headerBuf" << endl; return -1; } //memcpy( tmp, headerBuf, HEADER_BUF_SIZE-1 ); strncpy( tmp, headerBuf, strlen(headerBuf)+1 ); *fileHeadBuf = tmp; *fileBuf = pageBuf; } //close(sock); *nPSock = sock; return bytesRead;} int CHttp::CreateSocket(const char *host, int port){ int sock; // Socket descriptor struct sockaddr_in sa; // Socket address unsigned long inaddr; int ret; CUrl url; char *ip = url.GetIpByHost(host); if( ip == NULL ){ // gethostbyname() error in GetIpByHost() //cout << "invalid host: " << host << endl; return -1; } else { // filter ip (decide whether it is inside the ip block) if( url.IsValidIp(ip) ){ // inside inaddr = (unsigned long)inet_addr(ip); if( inaddr == INADDR_NONE ){ // release the buffer, be careful //pthread_mutex_lock(&mutexMemory); delete [] ip; ip = NULL; //pthread_mutex_unlock(&mutexMemory); cout << "invalid ip " << ip << endl; return -1; } memcpy((char *)&sa.sin_addr, (char *)&inaddr, sizeof(inaddr)); // release the buffer, be carful //pthread_mutex_lock(&mutexMemory); delete [] ip; ip = NULL; //pthread_mutex_unlock(&mutexMemory); } else { // out of ip block // release the buffer, be carful //pthread_mutex_lock(&mutexMemory); delete [] ip; ip = NULL; //pthread_mutex_unlock(&mutexMemory); //cout << "out of ip block: " << host << endl; return -2; } } /* Copy host address from hostent to (server) socket address */ sa.sin_family = AF_INET; sa.sin_port = htons(port); /* Put portnum into sockaddr */ sock = -1; sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0 ) { cout << "socket() in CreateSocket" << endl; return -1; } int optval = 1; if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof (optval)) < 0){ cout << "setsockopt() in CreateSocket" << endl; close(sock); return -1; } //ret = connect(sock, (struct sockaddr *)&sa, sizeof(sa)); ret = nonb_connect(sock, (struct sockaddr *)&sa, DEFAULT_TIMEOUT); if(ret == -1) { cout << "nonb_connect() in CreateSocket" << endl; close(sock); return -1; } return sock;} int CHttp::read_header(int sock, char *headerPtr){ fd_set rfds; struct timeval tv; int bytesRead = 0, newlines = 0, ret, selectRet; int flags; flags=fcntl(sock,F_GETFL,0); if(flags<0){ cout << "1.fcntl() in read_header()< 0" << endl; return -1; } flags|=O_NONBLOCK; if(fcntl(sock,F_SETFL,flags)<0){ cout << "2.fcntl() < 0 in read_header()" << endl; return -1; } while(newlines != 2 && bytesRead != HEADER_BUF_SIZE-1) { FD_ZERO(&rfds); FD_SET(sock, &rfds); tv.tv_sec = timeout; tv.tv_usec = 0; if(timeout >= 0) selectRet = select(sock+1, &rfds, NULL, NULL, &tv); else /* No timeout, can block indefinately */ selectRet = select(sock+1, &rfds, NULL, NULL, NULL); if(selectRet == 0 && timeout < 0) { cout << "selectRet == 0 && timeout < 0" << endl; return -1; }else if(selectRet == -1) { cout << "selectRet == 0 && timeout < 0 else" << endl; return -1; } ret = read(sock, headerPtr, 1); if(ret == -1){ cout << "!error: read() in read_header()" << endl; return -1; } bytesRead++; if(*headerPtr == '\r') { /* Ignore CR */ /* Basically do nothing special, just don't set newlines * to 0 */ headerPtr++; continue; } else if(*headerPtr == '\n') /* LF is the separator */ newlines++; else newlines = 0; headerPtr++; } //headerPtr -= 3; /* Snip the trailing LF's */ /* to be compatible with Tianwang format, we have to retain them*/ headerPtr -= 2; *headerPtr = '\0'; //cout << "in it " << headerPtr << endl; return bytesRead;}/* *function nonblocking connect *parameter sec is the second of timing out */int CHttp::nonb_connect(int sockfd,struct sockaddr* sa,int sec){ int flags; int status; fd_set mask; struct timeval timeout; //set the socket as nonblocking flags=fcntl(sockfd,F_GETFL,0); if(flags<0) return -1; flags|=O_NONBLOCK; if(fcntl(sockfd,F_SETFL,flags) < 0){ cout << "1.fcntl() in nonb_connect" << endl; return -1; } if( connect(sockfd,sa,sizeof(struct sockaddr)) == 0){ flags&=~O_NONBLOCK; fcntl(sockfd,F_SETFL,flags); return sockfd;//connected immediately } FD_ZERO(&mask); FD_SET(sockfd,&mask); timeout.tv_sec=sec; timeout.tv_usec=0; status=select(sockfd+1,NULL,&mask,NULL,&timeout); switch(status){ case -1: // Select error, set the socket as default blocking flags&=~O_NONBLOCK; fcntl(sockfd,F_SETFL,flags); cout << "2.fcntl() in nonb_connect" << endl; return -1; case 0: //Connection timed out. flags&=~O_NONBLOCK; fcntl(sockfd,F_SETFL,flags); cout << "3.fcntl() in nonb_connect" << endl; return -1; default: // Connected successfully. FD_CLR(sockfd,&mask); flags&=~O_NONBLOCK; fcntl(sockfd,F_SETFL,flags); return 0; }} /* * Determines if the given NULL-terminated buffer is large enough to * concatenate the given number of characters. If not, it attempts to * grow the buffer to fit. * Returns: * 0 on success, or * -1 on error (original buffer is unchanged). */int CHttp::checkBufSize(char **buf, int *bufsize, int more){ char *tmp; int roomLeft = *bufsize - (strlen(*buf) + 1); if(roomLeft > more) return 0; //pthread_mutex_lock(&mutexMemory); tmp = (char *)realloc(*buf, *bufsize + more + 1); //pthread_mutex_unlock(&mutexMemory); if(tmp == NULL) return -1; *buf = tmp; *bufsize += more + 1; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -