int open_write_file(http_connect_t *con) { request * in; response *out; buffer *uri, *tmp, *dir; char *ptr ; FILE * fp; pool_t *p = con->p; int count = 0; in = con->in; out = con->out; uri = buffer_init(p); uri->ptr = in->uri->ptr; uri->used = uri->size = in->uri->len; dir = buffer_create_size(con->p, in->uri->len); memcpy(dir->ptr, uri->ptr, uri->used); ptr = dir->ptr + uri->used; dir->used = uri->used; while(ptr >= dir->ptr) { if(*ptr == '/') { *ptr = '\0'; break; } ptr--; dir->used--; } uri->ptr[uri->used] = '\0'; if(dir->used) { int ret = _mkdir(con, dir->ptr, p); if(ret == -1) { return 0; } } ptr = (char *) palloc(p, sizeof(char)*2048); fp = fopen(uri->ptr, "w"); if(fp) { make_fd_non_blocking(fileno(fp)); con->write_file.fp = fp; con->write_file.len = 0; con->next_handle = write_file_content; } else { int logStrLen = strlen(dir) + 30; char * logStr = (char *) palloc(p, logStrLen); snprintf(logStr, logStrLen, "[access %s Permission denied]", dir ); ds_log(con, logStr, LOG_LEVEL_ERROR); con->next_handle = send_put_forbidden_result; } return 0; }
int parse_cgi(epoll_cgi_t *cgi) { list_buffer *cgi_data, *send; buffer *b; char *p; int count; buffer *header, *out, *tmp; cgi_data = cgi->cgi_data; if(cgi_data == NULL || cgi_data->b == NULL || cgi_data->b->ptr == NULL || cgi_data->b->size == 0) return 0; b = cgi_data->b; send = (list_buffer *) pcalloc(cgi->con->p, sizeof(list_buffer)); header = (buffer *) pcalloc(cgi->con->p, sizeof(buffer)); cgi->con->out->status_code = HTTP_OK; p = strstr(b->ptr,"\n\n"); if(p != NULL && (p-b->ptr) < b->size) { buffer_n_to_lower(b, (p-b->ptr)+1); header->ptr = b->ptr; header->size = (p-b->ptr) + 2; tmp = (buffer *) pcalloc(cgi->con->p, sizeof(buffer)); buffer_find_str(header, tmp, "content-type:"); if(tmp->ptr == NULL) { send_bad_gateway(cgi->con->fd); return 1; } p = tmp->ptr + tmp->size; while(*p == ' ') p++; tmp->ptr = p; p = strchr(p, '\n'); count = p - tmp->ptr ; if(*(p-1) != '\r' ) count++; tmp->size = count; cgi->con->out->content_type = buffer_create_size(cgi->con->p, count); cgi->con->out->content_type->size = count; strncpy(cgi->con->out->content_type->ptr, tmp->ptr, count -1); cgi->con->out->content_type->ptr[count-1] = 0; out = (buffer *)pcalloc(cgi->con->p, sizeof(buffer)); out->ptr = header->ptr + header->size; out->size = b->size - header->size; send->b = out; send->next = cgi_data->next; cgi->out = send; } }
int start_cgi(http_conf *g) { execute_cgi_info_manager_t * cgi_info_manager ; struct epoll_event ev[MAX_EVENT]; struct epoll_event *evfd ; int count; buffer *header; epoll_extra_data_t *epoll_data; int i = 0; hash_item_t * hitem; epoll_cgi_t * executeCgi; int evIndex; g_goabal = g; cgi_info_manager = cgi_info_manager_gloabal = initCgiManager(); header = buffer_create_size(cgi_info_manager->p, 1024); start_cgi_server(g, cgi_info_manager); printf("--------------- start execute sh server\n"); signal(SIGCHLD, signalhld_handle); while(1) { count = epoll_wait(g->epfd, ev, MAX_EVENT, -1); //收集所有需要需要执行cgi文件的 while(read_cgi_header(header, g->fd) == 0) { parse_cig_header(cgi_info_manager, header); header->used = 0; } //处理正在执行cgi文件 if(count < 0) { continue;} evfd = ev; for(evIndex = 0; evIndex < count; evIndex++){ if(evfd->events & EPOLLIN) { epoll_data = ev->data.ptr; switch(epoll_data->type) { case CGIFD: get_cgi_operator_handle((epoll_cgi_t *)epoll_data->ptr); break; } } evfd++; } //开始执行cgi任务, 其实可以用回调函数或者hash_filter返回可用的数据。然而我不回写如何将函数做为参数 for(i = 0; i < cgi_info_manager->h->size; i++) { hitem = cgi_info_manager->h->buckets[i].items; while(hitem) { if(hitem->type == HASH_ITEM_VALUE_TYPE_PTR) { executeCgi = (epoll_cgi_t *)hitem->value.ptr; if(executeCgi->status == CGI_STATUS_RUN && executeCgi->last_run_ts < executeCgi->last_add_ts) { printf("kill pid %d\n", executeCgi->pid); kill(executeCgi->pid, SIGKILL); } else if(executeCgi-> status != CGI_STATUS_CLOSEING ) { if(executeCgi->last_run_ts < executeCgi->last_add_ts ) {//执行时间小于 executeCgi->status = CGI_STATUS_CLOSEING; cgi_handle(executeCgi, g); } }else { printf("none \n"); } } hitem = hitem->next; } } } }