static int be_read(se_ptr_t *ptr) { epdata_t *epd = ptr->data; int n = recv(epd->fd, &buf_4096, 4096, 0); if(n > 0) { update_timeout(epd->timeout_ptr, 1000); if(network_raw_send(epd->fd, (const char *)&buf_4096, n)) { if(buf_4096[n - 1] == '\n') { buf_4096[n - 1] = '\0'; } LOGF(INFO, "%s", buf_4096); } else { LOGF(ERR, "send error!\n"); se_delete(epd->se_ptr); if(epd->fd > -1) { close(epd->fd); epd->fd = -1; } free(epd); } } else if(n == 0 || (n < 0 && NOAGAIN)) { // close connection se_delete(epd->se_ptr); if(epd->fd > -1) { close(epd->fd); epd->fd = -1; } free(epd); } else { LOGF(ERR, "read error!\n"); } return 1; }
static int network_be_read ( se_ptr_t *ptr ) { epdata_t *epd = ptr->data; if ( !epd ) { return 0; } int n = 0; update_timeout ( epd->timeout_ptr, STEP_READ_TIMEOUT ); if ( epd->headers == NULL ) { epd->headers = &epd->iov; epd->buf_size = sizeof ( epd->iov ); } else if ( epd->data_len == epd->buf_size ) { if ( epd->headers == &epd->iov ) { epd->headers = malloc ( 4096 * 2 ); memcpy ( epd->headers, &epd->iov, sizeof ( epd->iov ) ); epd->buf_size = 4096 * 2; } else { char *_t = ( char * ) realloc ( epd->headers, epd->buf_size + 4096 ); if ( _t != NULL ) { epd->headers = _t; } else { epd->iov[0].iov_base = NULL; epd->iov[0].iov_len = 0; epd->iov[1].iov_base = NULL; epd->iov[1].iov_len = 0; network_send_error ( epd, 503, "memory error!" ); close_client ( epd ); serv_status.reading_counts--; return 0; } epd->buf_size += 4096; } } while ( ( n = recv ( epd->fd, epd->headers + epd->data_len, epd->buf_size - epd->data_len, 0 ) ) >= 0 ) { if ( n == 0 ) { close_client ( epd ); epd = NULL; break; } if ( epd->data_len + n >= epd->buf_size ) { if ( epd->headers == &epd->iov ) { epd->headers = malloc ( 4096 * 2 ); memcpy ( epd->headers, &epd->iov, sizeof ( epd->iov ) ); epd->buf_size = 4096 * 2; } else { char *_t = ( char * ) realloc ( epd->headers, epd->buf_size + 4096 ); if ( _t != NULL ) { epd->headers = _t; } else { epd->iov[0].iov_base = NULL; epd->iov[0].iov_len = 0; epd->iov[1].iov_base = NULL; epd->iov[1].iov_len = 0; network_send_error ( epd, 503, "memory error!" ); close_client ( epd ); serv_status.reading_counts--; return 0; } epd->buf_size += 4096; } } if ( epd->status != STEP_READ ) { serv_status.reading_counts++; epd->status = STEP_READ; epd->data_len = n; epd->start_time = longtime(); } else { epd->data_len += n; } if ( epd->_header_length < 1 && epd->data_len >= 4 && epd->headers ) { int _get_content_length = 0; if ( epd->headers[epd->data_len - 1] == '\n' && ( epd->headers[epd->data_len - 2] == '\n' || ( epd->headers[epd->data_len - 4] == '\r' && epd->headers[epd->data_len - 2] == '\r' ) ) ) { epd->_header_length = epd->data_len; } else { _get_content_length = 1; unsigned char *fp2 = stristr ( epd->headers, "\r\n\r\n", epd->data_len ); if ( fp2 ) { epd->_header_length = ( fp2 - epd->headers ) + 4; } else { fp2 = stristr ( epd->headers, "\n\n", epd->data_len ); if ( fp2 ) { epd->_header_length = ( fp2 - epd->headers ) + 2; } } } if ( epd->_header_length > 0 && epd->content_length < 0 ) { /// not POST or PUT request if ( _get_content_length == 0 && epd->headers[0] != 'P' && epd->headers[0] != 'p' ) { epd->content_length = 0; } else { int flag = 0; unsigned char *fp = stristr ( epd->headers, "\ncontent-length:", epd->data_len ); if ( fp ) { int fp_at = fp - epd->headers + 16; int i = 0, _oc; for ( i = fp_at; i < epd->data_len; i++ ) { if ( epd->headers[i] == '\r' || epd->headers[i] == '\n' ) { flag = 1; fp = epd->headers + fp_at; _oc = epd->headers[i]; epd->headers[i] = '\0'; break; } } if ( flag ) { epd->content_length = atoi ( fp ); epd->headers[i] = _oc; } if ( stristr ( epd->headers + ( epd->_header_length - 60 ), "100-continue", epd->_header_length ) ) { network_raw_send ( epd->fd, "HTTP/1.1 100 Continue\r\n\r\n", 25 ); } } } } if ( epd->_header_length > 0 && epd->_header_length < epd->data_len && epd->content_length < 1 ) { epd->iov[0].iov_base = NULL; epd->iov[0].iov_len = 0; epd->iov[1].iov_base = NULL; epd->iov[1].iov_len = 0; network_send_error ( epd, 411, "" ); close_client ( epd ); epd = NULL; serv_status.reading_counts--; break; } } //printf("data_len = %d header_length = %d content_length = %d\n", epd->data_len, epd->_header_length, epd->content_length); if ( epd->_header_length > 0 && ( ( epd->content_length < 1 && epd->_header_length > 0 ) || epd->content_length <= epd->data_len - epd->_header_length ) ) { /// start job epd->header_len = epd->_header_length; epd->headers[epd->data_len] = '\0'; epd->header_len -= 1; epd->headers[epd->header_len] = '\0'; if ( epd->header_len + 1 < epd->data_len ) { epd->contents = epd->headers + epd->header_len + 1; } else { epd->content_length = 0; } if ( USE_KEEPALIVE == 1 && ( epd->keepalive == 1 || ( stristr ( epd->headers, "keep-alive", epd->header_len ) ) ) ) { epd->keepalive = 1; } epd->response_header_length = 0; epd->iov_buf_count = 0; epd->response_content_length = 0; epd->response_sendfile_fd = -1; /// output server status !!!!!!!!!! { int i, len; char *uri = NULL; uri = epd->headers; for ( i = 0; i < epd->header_len; i++ ) if ( uri[i] == ' ' ) { break; } for ( ; i < epd->header_len; i++ ) if ( uri[i] != ' ' ) { break; } uri = epd->headers + i; len = strlen ( uri ); for ( i = 0; i < len; i++ ) { if ( uri[i] == '\r' || uri[i] == '\n' || uri[i] == ' ' ) { break; } } if ( i > 11 && strncmp ( "/serv-status", uri, i ) == 0 ) { epd->process_timeout = 0; epd->iov[0].iov_base = NULL; epd->iov[0].iov_len = 0; epd->iov[1].iov_base = NULL; epd->iov[1].iov_len = 0; network_send_status ( epd ); serv_status.reading_counts--; break; } } /// end. se_be_pri ( epd->se_ptr, NULL ); // be wait if ( epd->status == STEP_READ ) { serv_status.reading_counts--; epd->status = STEP_PROCESS; serv_status.sec_process_counts[ ( now ) % 5]++; serv_status.process_counts++; epd->method = NULL; epd->uri = NULL; epd->host = NULL; epd->query = NULL; epd->http_ver = NULL; epd->referer = NULL; epd->user_agent = NULL; if ( process_func ( epd, 0 ) != 0 ) { close_client ( epd ); epd = NULL; } } break; } } if ( epd && n < 0 && errno != EAGAIN && errno != EWOULDBLOCK ) { //printf("error fd %d (%d) %s\n", epd->fd, errno, strerror(errno)); close_client ( epd ); epd = NULL; return 0; } return 1; }
void network_be_end ( epdata_t *epd ) // for lua function die { if ( epd->process_timeout == 1 && epd->keepalive != -1 ) { epd->process_timeout = 0; free_epd ( epd ); return; } //printf ( "network_be_end %d\n" , ((se_ptr_t*)epd->se_ptr)->fd ); update_timeout ( epd->timeout_ptr, STEP_SEND_TIMEOUT ); se_be_write ( epd->se_ptr, network_be_write ); serv_status.success_counts++; epd->status = STEP_SEND; serv_status.sending_counts++; if ( epd->iov[0].iov_base == NULL && epd->iov[1].iov_base == NULL && epd->response_sendfile_fd == -1 ) { serv_status.sending_counts--; network_send_error ( epd, 417, "" ); } else if ( epd->response_sendfile_fd == -2 ) { epd->response_sendfile_fd = -1; serv_status.sending_counts--; network_send_error ( epd, 404, "File Not Found!" ); } else { int gzip_data = 0; //printf("%d %s\n", epd->response_content_length, epd->iov[1].iov_base); if ( epd->response_content_length > 1024 && epd->iov[1].iov_base && !is_binary ( epd->iov[1].iov_base, epd->iov[1].iov_len ) ) { char *p = NULL; if ( epd->headers ) { p = stristr ( epd->headers, "Accept-Encoding", epd->header_len ); } if ( p ) { p += 16; int i = 0, m = strlen ( p ); for ( ; i < 20 && i < m; i++ ) { if ( p[i] == '\n' ) { break; } } p[i] = '\0'; if ( strstr ( p, "deflate" ) ) { gzip_data = 2; } else if ( strstr ( p, "gzip" ) ) { gzip_data = 1; } p[i] = '\n'; } } if ( gzip_data > 0 ) epd->response_content_length = gzip_iov ( gzip_data, ( struct iovec * ) &epd->iov, epd->iov_buf_count, &epd->iov_buf_count ); int len = 0; if ( epd->iov[0].iov_base == NULL ) { len = sprintf ( temp_buf, "HTTP/1.1 200 OK\r\nServer: aLiLua/%s (%s)\r\nContent-Type: text/html; charset=UTF-8\r\nConnection: %s\r\n%sContent-Length: %d\r\n\r\n", version, hostname, ( epd->keepalive == 1 ? "keep-alive" : "close" ), ( gzip_data == 1 ? "Content-Encoding: gzip\r\n" : ( gzip_data == 2 ? "Content-Encoding: deflate\r\n" : "" ) ), epd->response_content_length + ( gzip_data == 1 ? 10 : 0 ) ); epd->response_header_length = len; } else { //( ( char * ) ( epd->iov[0].iov_base ) ) [epd->response_header_length] = '\0'; memcpy ( temp_buf, epd->iov[0].iov_base, epd->response_header_length ); len = epd->response_header_length + sprintf ( temp_buf + epd->response_header_length, "Server: aLiLua/%s (%s)\r\nConnection: %s\r\nDate: %s\r\n%sContent-Length: %d\r\n\r\n", version, hostname, ( epd->keepalive == 1 ? "keep-alive" : "close" ), now_date, ( gzip_data == 1 ? "Content-Encoding: gzip\r\n" : ( gzip_data == 2 ? "Content-Encoding: deflate\r\n" : "" ) ), epd->response_content_length + ( gzip_data == 1 ? 10 : 0 ) ); epd->response_header_length += len; } if ( len < 4086 && epd->response_sendfile_fd <= -1 && epd->iov[1].iov_base && epd->iov[1].iov_len > 0 ) { if ( epd->iov[0].iov_base == NULL ) { epd->iov[0].iov_base = malloc ( EP_D_BUF_SIZE ); } if ( epd->iov[0].iov_base == NULL ) { epd->keepalive = 0; network_end_process ( epd ); serv_status.sending_counts--; return; } memcpy ( epd->iov[0].iov_base, temp_buf, len ); epd->iov[0].iov_len = len; epd->response_content_length += len; if ( gzip_data == 1 ) { memcpy ( epd->iov[0].iov_base + len, gzip_header, 10 ); epd->iov[0].iov_len += 10; epd->response_content_length += 10; } epd->iov_buf_count += 1; } else { network_raw_send ( epd->fd, temp_buf, len ); if ( gzip_data == 1 ) { network_raw_send ( epd->fd, gzip_header, 10 ); } free ( epd->iov[0].iov_base ); epd->iov[0].iov_base = NULL; int i = 0; for ( i = 0; i < epd->iov_buf_count; i++ ) { epd->iov[i] = epd->iov[i + 1]; epd->iov[i + 1].iov_base = NULL; epd->iov[i + 1].iov_len = 0; } } //epd->response_header_length = 0; //printf("%d\n", epd->response_header_length); if ( epd->response_content_length == 0 ) { network_end_process ( epd ); serv_status.sending_counts--; } else { epd->response_buf_sended = 0; } } }