Пример #1
0
void
hio_response_http_send_headers(HioResponseHttp *http)
{
    /* FIXME send actual headers */

    g_mutex_lock(http->headers_lock);

    /* Sending headers twice is allowed, for example request handlers
     * can do it early, but a container might do it automatically
     * after the request handler runs. Only first send does anything
     * of course and it's an error to try to set headers after we
     * already sent them.
     */
    if (http->headers_sent) {
        g_mutex_unlock(http->headers_lock);
        return;
    }
    http->headers_sent = TRUE;

    write_to_header(http, "HTTP/1.1 200 OK\r\n");
    write_to_header(http, "Date: Wed, 21 Jul 2010 02:24:36 GMT\r\n");
    write_to_header(http, "Server: hrt/" VERSION "\r\n");
    write_to_header(http, "Last-Modified: Tue, 01 Dec 2009 23:10:05 GMT\r\n");
    write_to_header(http, "Content-Type: text/html\r\n");
    write_to_header(http, "Connection: close\r\n");
    write_to_header(http, "\r\n");

    hio_output_stream_close(http->header_stream);

    g_mutex_unlock(http->headers_lock);
}
Пример #2
0
void read_request ( struct process* process )
{
    int sock = process->sock, s;
    char* buf=process->buf;
    char read_complete = 0;

    ssize_t count;

    while ( 1 )
    {
        count = read ( sock, buf + process->read_pos, BUF_SIZE - process->read_pos );
        if ( count == -1 )
        {
            if ( errno != EAGAIN )
            {
                handle_error ( process, "read request" );
                return;
            }
            else
            {
                //errno == EAGAIN表示读取完毕
                break;
            }
        }
        else if ( count == 0 )
        {
            // 被客户端关闭连接
            cleanup ( process );
            return;
        }
        else if ( count > 0 )
        {
            process->read_pos += count;
        }
    }

    int header_length = process->read_pos;
    // determine whether the request is complete
    if ( header_length > BUF_SIZE - 1 )
    {
	process->response_code = 400;
	process->status = STATUS_SEND_RESPONSE_HEADER;
	strcpy ( process->buf, header_400 );
	send_response_header ( process );
	handle_error ( processes, "bad request" );
	return;
    }
    buf[header_length]=0;
    read_complete = ( strstr ( buf, "\n\n" ) != 0 ) || ( strstr ( buf, "\r\n\r\n" ) != 0 );

    int error = 0;
    if ( read_complete )
    {
        //重置读取位置
        reset_process ( process );
        // get GET info
        if ( !strncmp ( buf, "GET", 3 ) == 0 )
        {
            process->response_code = 400;
            process->status = STATUS_SEND_RESPONSE_HEADER;
            strcpy ( process->buf, header_400 );
            send_response_header ( process );
            handle_error ( processes, "bad request" );
            return;
        }
        // get first line
        int n_loc = ( int ) strchr ( buf, '\n' );
        int space_loc = ( int ) strchr ( buf + 4, ' ' );
        if ( n_loc <= space_loc )
        {
            process->response_code = 400;
            process->status = STATUS_SEND_RESPONSE_HEADER;
            strcpy ( process->buf, header_400 );
            send_response_header ( process );
            handle_error ( processes, "bad request" );
            return;
        }
        char path[255];
        int len = space_loc - ( int ) buf - 4;
        if ( len > MAX_URL_LENGTH )
        {
            process->response_code = 400;
            process->status = STATUS_SEND_RESPONSE_HEADER;
            strcpy ( process->buf, header_400 );
            send_response_header ( process );
            handle_error ( processes, "bad request" );
            return;
        }
        buf[header_length] = 0;
        strncpy ( path, buf+4, len );
        path[len] = 0;

        struct stat filestat;
        char fullname[256];
        char *prefix = doc_root;
        strcpy ( fullname, prefix );
        strcpy ( fullname + strlen ( prefix ), path );
        s = get_index_file ( fullname, &filestat);
        if ( s == -1 )
        {
            process->response_code = 404;
            process->status = STATUS_SEND_RESPONSE_HEADER;
            strcpy ( process->buf, header_404 );
            send_response_header ( process );
            handle_error ( processes, "not found" );
            return;
        }

        int fd = open ( fullname, O_RDONLY );

        process->fd = fd;
        if ( fd<0 )
        {
            process->response_code = 404;
            process->status = STATUS_SEND_RESPONSE_HEADER;
            strcpy ( process->buf, header_404 );
            send_response_header ( process );
            handle_error ( processes, "not found" );
            return;
        }
        else
        {
            process->response_code = 200;
        }
	
        char tempstring[256];

        //检查有无If-Modified-Since,返回304
        char* c = strstr ( buf, HEADER_IF_MODIFIED_SINCE );
	if(c!=0){
	    char* rn = strchr(c, '\r');
	    if(rn==0){
	      rn = strchr(c, '\n');
	      if(rn==0){
		  process->response_code = 400;
		  process->status = STATUS_SEND_RESPONSE_HEADER;
		  strcpy ( process->buf, header_400 );
		  send_response_header ( process );
		  handle_error ( processes, "bad request" );
		  return;
	      }
	    }
	  int time_len = rn - c - sizeof(HEADER_IF_MODIFIED_SINCE) + 1;
	  strncpy(tempstring, c + sizeof(HEADER_IF_MODIFIED_SINCE) - 1,time_len);
	  tempstring[time_len]=0;
	  {
	    struct tm tm;
	    time_t t;
	    strptime(tempstring, RFC1123_DATE_FMT, &tm);
	    tzset();
	    t=mktime(&tm);
	    t-=timezone;
	    gmtime_r(&t, &tm);
	    if(t >= filestat.st_mtime){
	      process->response_code = 304;
	    }
	  }
	}

        //开始header
        process->buf[0] = 0;
	if(process->response_code == 304){
	  write_to_header ( header_304_start );
	} else {
	  write_to_header ( header_200_start );
	}

        process->total_length = filestat.st_size;

	{
	  //写入当前时间
	  struct tm *tm;
	  time_t tmt;
	  tmt = time ( NULL );
	  tm = gmtime ( &tmt );
	  strftime ( tempstring, sizeof ( tempstring ), RFC1123_DATE_FMT, tm );
	  write_to_header ( "Date: " );
	  write_to_header ( tempstring );
	  write_to_header ( "\r\n" );

	  //写入文件修改时间
	  tm = gmtime ( &filestat.st_mtime );
	  strftime ( tempstring, sizeof ( tempstring ), RFC1123_DATE_FMT, tm );
	  write_to_header ( "Last-modified: " );
	  write_to_header ( tempstring );
	  write_to_header ( "\r\n" );

	  if(process->response_code == 200){
	    //写入content长度
	    sprintf ( tempstring, "Content-Length: %ld\r\n", filestat.st_size );
	    write_to_header ( tempstring );
	  }
	}

        //结束header
        write_to_header ( header_end );

        process->status = STATUS_SEND_RESPONSE_HEADER;
        //修改此sock的监听状态,改为监视写状态
        event.data.fd = process->sock;
        event.events = EPOLLOUT | EPOLLET;
        s = epoll_ctl ( efd, EPOLL_CTL_MOD, process->sock, &event );
        if ( s == -1 )
        {
            perror ( "epoll_ctl" );
            abort ();
        }
        //发送header
        send_response_header ( process );
    }
}