Пример #1
0
ssize_t 
rio_readnb(rio_t *rp, void *usrbuf, size_t n)
{
	size_t nleft = n;
	ssize_t nread;
	char *bufp = usrbuf;
	
	while(nleft > 0) {
		if ((nread = rio_readn(rp->rio_fd, bufp, nleft)) < 0)	
		{
			if(errno == EINTR ||
			   errno == EAGAIN ||
			   errno == EWOULDBLOCK)
			{ //线程不安全
				nread = 0;
			} else {
				return -1;
			}
		} else if(nread == 0)
			break;
		nleft -= nread;
		bufp += nread;
	}

	return (n-nleft);
}
Пример #2
0
/* $begin serve_static */
void serve_static(int fd, char *filename, int filesize) 
{
    int srcfd;
    char *srcp, filetype[MAXLINE], buf[MAXBUF];

	int n;
	srcp = malloc(filesize);
 
    /* Send response headers to client */
    get_filetype(filename, filetype);       //line:netp:servestatic:getfiletype
    sprintf(buf, "HTTP/1.0 200 OK\r\n");    //line:netp:servestatic:beginserve
    sprintf(buf, "%sServer: Tiny Web Server\r\n", buf);
    sprintf(buf, "%sContent-length: %d\r\n", buf, filesize);
    sprintf(buf, "%sContent-type: %s\r\n\r\n", buf, filetype);
    Rio_writen(fd, buf, strlen(buf));       //line:netp:servestatic:endserve

    /* Send response body to client */
    srcfd = Open(filename, O_RDONLY, 0);    //line:netp:servestatic:open
    //srcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd, 0);//line:netp:servestatic:mmap
    while ((n = rio_readn(srcfd, srcp, filesize + 1)) != 0)
	 { Rio_writen(fd, srcp, filesize); }
	 Close(srcfd);                           //line:netp:servestatic:close
    free(srcp);
	 // Rio_writen(fd, srcp, filesize);         //line:netp:servestatic:write
    // Munmap(srcp, filesize);                 //line:netp:servestatic:munmap
}
Пример #3
0
/**********************************
 *  * Wrappers for robust I/O routines
 *   **********************************/
ssize_t Rio_readn(int fd, void *ptr, size_t nbytes) 
{
	ssize_t n;	  
	if ((n = rio_readn(fd, ptr, nbytes)) < 0)
		unix_error("Rio_readn error");
	return n;
}
Пример #4
0
ssize_t Rio_readn(int fd, void *userbuf, size_t n)
{
	ssize_t rt;
	rt = rio_readn(fd, userbuf, n);
	if (rt == -1)
		unix_error("Rio_readn error");
	return rt;
}
Пример #5
0
ssize_t Rio_readn_s(int fd, void *ptr, size_t nbytes){
    ssize_t n;
    if ((n = rio_readn(fd, ptr, nbytes)) < 0){
			printf("Rio_readn error\n");
			n = 0;
		}
    return n;
}
Пример #6
0
/**********************************
 * Wrappers for robust I/O routines
 **********************************/
ssize_t Rio_readn(int fd, void *ptr, size_t nbytes) 
{
    ssize_t n;
  
    if ((n = rio_readn(fd, ptr, nbytes)) < 0) {
        if (errno != ECONNRESET)
	    unix_error("Rio_readn error");
    }
    return n;
}
Пример #7
0
int main()
{
	int n;
	rio_t rio;
	char buf[MAXLINE];

	rio_readinitb(&rio, STDIN_FILENO);

	whle((n= rio_readn(&rio, buf, MAXBUF)) != 0)
		Rio_writen(STDOUT_FILENO, buf, MAXBUF);

	return 0;
}
ssize_t Rio_readn(int fd, void *ptr, size_t nbytes) {
	ssize_t n;

	if ((n = rio_readn(fd, ptr, nbytes)) < 0) {
		if (errno != EPIPE)
			unix_error("Rio_readn error");
		else {
			//	   printf("Rio_readn: socket has closed with EPIPE\n");
			return -1;
		}
	}

	return n;
}
Пример #9
0
bool page::read_full_page(int fd) {
    
    /* create an aligned array of bytes we can read into */
    void* aligned_base;
    guard<char> ptr =
        (char*)aligned_alloc(page_size(), 512, &aligned_base);
    assert(ptr != NULL);


    /* read bytes over 'this' */
    /* read system call may return short counts */
    ssize_t size_read = rio_readn(fd, aligned_base, page_size());


    /* check for error */
    if (size_read == -1)
        THROW2(FileException, "::read failed %s", strerror(errno));

    
    /* check for end of file */
    if (size_read == 0)
        return false;


    /* rio_readn ensures we read the proper number of bytes */
    /* save page attributes that we'll be overwriting */
    page_pool* pool  = _pool;
    memcpy(this, aligned_base, size_read);
    _pool = pool;

    
    /* more error checking */
    if ( (page_size() != (size_t)size_read) ) {
        /* The page we read does not have the same size as the
           page object we overwrote. Luckily, we used the object
           size when reading, so we didn't overflow our internal
           buffer. */
        TRACE(TRACE_ALWAYS,
              "Read %zd byte-page with internal page size of %zd bytes. "
              "Sizes should all match.\n",
              size_read,
              page_size());
        THROW1(FileException, "::read read wrong size page");
    }
    
    return true;
}
Пример #10
0
char* networkClient::run(const std::string& wholeMessage) {
	std::string response;
	if(!isCreated()) createSocket();
	connectSocket();

	//Send this command to the network server
	char *buffer;
	buffer = new char[8192];
	n = write(sockfd,wholeMessage.c_str(),wholeMessage.length());
	fprintf(stdout,"Message wrote\n");
	if (n < 0) fprintf(stderr,"ERROR writing to socket");
	n = rio_readn(sockfd,buffer,8191);
	fprintf(stdout,"Message recv\n");
	if (n < 0) fprintf(stderr,"ERROR reading from socket");
	
	return(buffer);
}
Пример #11
0
Файл: io.c Проект: Lw-Cui/proxy
ssize_t rio_readline(int fd, void *usrbuf, size_t maxlen) {
	int n, rc;
	char c, *buf = usrbuf;
	for (n = 1; n < maxlen; n++)
		if ((rc = rio_readn(fd, &c, 1)) == 1) {
			*buf++ = c;
			if (c == '\n')
				break;
		} else if (rc == 0) {
			if (n == 1)
				return 0;
			else
				break;
		} else {
			return -1;
		}

		*buf = 0;
		return n;
}
Пример #12
0
/* Wrapper for read (unbuffered) */
ssize_t Rio_readn(int fd, void *ptr, size_t nbytes) 
{
    ssize_t n;
    n = rio_readn(fd, ptr, nbytes);
    return n;
}
Пример #13
0
/* Analyze the request from browser and decide whether retrieve from
 * cache or connect to the server*/
void* request (void* data){
    pthread_detach(pthread_self());
    Signal(SIGPIPE,SIG_IGN);
    signal(SIGPIPE,SIG_IGN);
    int serverfd=*(int*)data;
    int clientfd;
    char headerBuff[MAXHEADERSIZE],Buffer[MAXBUFFERSIZE];
    char hostname[300],uriname[MAXHEADERSIZE],urlname[MAXHEADERSIZE];
    char* cache_buff;
    int getbyte,error;
    int cachehit = 0;
    int cache_size = 0;
    free(data);
    rio_t serverrio_t;

    rio_readinitb(&serverrio_t,serverfd);

    rio_readlineb(&serverrio_t,headerBuff,sizeof(headerBuff));
    if (takeHostUriUrl(headerBuff,hostname,uriname,urlname) ==0){
        perror("Get Host Uri Url error\n");
        close(serverfd);
        pthread_exit(NULL);
    }
    /* Try to get cached data, must check no thread writing the cache,
     *      * and use FILO architecture to lock when there threads reading cache*/

    P(&mutex);
    readcnt++;
    if(readcnt == 1)
        P(&w);
    V(&mutex);
    if( Get_cachedata(urlname,serverfd) > 0){
        cachehit = 1;
    }

    P(&mutex);
    readcnt--;
    if(readcnt == 0)
        V(&w);
    V(&mutex);

    if(cachehit){
        printf("Cache Hit!!!!\n");
        close(serverfd);
        pthread_exit(NULL);
    }




    if( (clientfd=socket(AF_INET,SOCK_STREAM,0))<0){
        perror("socket");
        close(serverfd);
        pthread_exit(NULL);
    }
    /*get server's address info*/
    struct addrinfo *hostinfo;
    if( (error=getaddrinfo(hostname,"http",NULL,&hostinfo)) >0){
        perror("hostinfo");
        close(serverfd);
        close(clientfd);
        pthread_exit(NULL);
    }
    /* connect to the server*/
    if( (connect(clientfd,hostinfo->ai_addr,hostinfo->ai_addrlen))<0){
        perror("connect");
        close(serverfd);
        close(clientfd);
        return NULL;
    }

    cache_buff = (char*) malloc(MAX_OBJECT_SIZE*sizeof(char));
    cache_size = 0;

    /* Send the request to the server */

    SendRequest(clientfd,serverrio_t,hostname,uriname);
    /*read the information from web server and send it to browser*/
    while(1){
        getbyte = rio_readn(clientfd,Buffer,sizeof(Buffer));
        if(getbyte <= 0 )
            break;
        if(cache_size + getbyte < MAX_OBJECT_SIZE){
            memcpy(cache_buff + cache_size,Buffer,getbyte);
        }
        cache_size += getbyte;

        rio_writen(serverfd,Buffer,getbyte);
    }
    /* if size fit in cache, write into cache, else free the content*/
    if(cache_size < MAX_OBJECT_SIZE){
        char* new_cache_buff = realloc(cache_buff,cache_size);
        free(cache_buff);
        if(new_cache_buff == NULL){
            perror("Realloc fail\n");
            close(clientfd);
            close(serverfd);
            pthread_exit(NULL);
        }

        P(&w);
        char *saveurlname = (char*)malloc(strlen(urlname)*sizeof(char));
        memcpy(saveurlname,urlname,strlen(urlname));
        Create_cache(saveurlname,new_cache_buff,cache_size);
        V(&w);

    }
    else{
        free(cache_buff);
    }


    close(clientfd);
    close(serverfd);
    pthread_exit(NULL);

}
Пример #14
0
void* HttpRequest::RequestParse(void*arg)
{
	int n;
    int again_flag = true;   //again flag decide to close the fd or try again
    while(true)
    {
        errno = 0;                        //this is important
        memset(usr_buf,0,RIO_BUFSIZE);    //reset the buf
        n = rio_readn(fd,(void*)usr_buf,RIO_BUFSIZE-1);
        
        if(n==-1)
        {
            debug("error.");
            again_flag = false;
    	    break;
        }
        else if(n==0)
        {
            if(errno==EAGAIN)
            {
                //debug("again read");
                again_flag = true;
            }
            else  //EOF
            {
                //debug("EOF read close fd");
                again_flag = false;
            }
            //debug("there is not any more data,errno is: %d",errno);
            break;
        }

        read_data = usr_buf;
        /*
        cout<<"read data:--------------------------------------------"<<endl;
        cout<<read_data<<endl;
        cout<<"-------------------------------------------------------"<<endl;
        */
        //debug_cpp(read_data.size());
        CommandParse();    //requese line parse
        HeaderParse();     //head parse

        //int data_n = read_data.size();
        if(read_data.size()!=0)
        {
            BodyParse();   //body parse
        }

        /*parse complete,do method,url ,version check*/
        HttpError e;
        int check_res = e.RequireCheck(command,head,out,file_stat);


        if(check_res!=D_OK)
        {

            //debug("require error: %d",check_res);    //then send the wrong information page 
            command.uri = "/40x.html";
            // reset the file_stat;
            string file_name = file_root+command.uri;
            stat(file_name.c_str(),&file_stat);
            out.SetStaticServer(true);
        }
        
        /**********check over,send the result to the client********/

        if(out.GetStaticServer())  
        {
              //set the length
            out.SetFileSize(file_stat.st_size);
        
            auto out_line = out.SetOutLine_C();
            out_line += out.SetOutHeaders_C(head); 
            char* res_line_buf = const_cast<char*>(out_line.c_str());
            n = rio_writen(fd,(void*)res_line_buf,strlen(res_line_buf));  //write command line

            //debug("send Response line and Out Header.");
            StaticServer();
            //debug("----------static server over-----------");
        }
        else //dynamic server
        {
            //debug("----------dynamic server on-------------");
            DynamicServer();
            //debug("----------dynamic server over-----------");
        }

        //server -------**over**----------
        
        if(head.head.find("Connection")==head.head.end()) //keep alive
        {
            again_flag = false;
            //debug("-----------no keep alive,will break---------");
            break;
        }
        else
        {
            again_flag = true;
        }
        
    }
    
    if(!again_flag)
    {
      //debug("close fd ,%d",fd);
      close(fd);    //close fd ,there is no other request
    }
    else
    {
        
        head.head.clear();                //clear the request head
        read_data="";
        again_flag = true;
        out.clear();                      //clear the output data
        

        InitHttpRequest(ep,fd,epfd);      //no need to initialize.because the ep,fd,and the epfd etc do not change
        ep->SetEpollEvent((void*)this,D_EPOLLIN|D_EPOLLET|D_EPOLLONESHOT);  //set event
        ep->EpollCTL(D_EPOLL_CTL_MOD,fd); //add fd to the event module

      
    }

    return NULL;
}