/* * Reads an HTTP request from stream (fd), and writes an HTTP response * containing: * * 1) If user requested an existing file, respond with the file * 2) If user requested a directory and index.html exists in the directory, * send the index.html file. * 3) If user requested a directory and index.html doesn't exist, send a list * of files in the directory with links to each. * 4) Send a 404 Not Found response. */ void handle_files_request(int fd) { struct http_request*request=http_request_parse(fd); char*fullpath,*fullfullpath; struct stat st; if(0==strcmp("GET",request->method)){ fullpath=conc(server_files_directory,request->path); if(0==stat(fullpath,&st)){ // file/dir exists if(S_ISREG(st.st_mode)){ // is file http_send_file(fd,fullpath); }else if(S_ISDIR(st.st_mode)){ // is dir fullfullpath=conc(fullpath,"/index.html"); if(0==stat(fullfullpath,&st)){ // has an index.html http_send_file(fd,fullfullpath); }else{ // hasnt. list files DIR*d=opendir(fullpath); struct dirent*di; http_start_response(fd,200); http_send_header(fd,"Content-type","text/html"); http_end_headers(fd); while(NULL!=(di=readdir(d))) http_send_anchor(fd,di->d_name); } free(fullfullpath); } }else{ // doesnt exist. error 404 http_start_response(fd,404); http_send_header(fd,"Content-type","text/html"); http_end_headers(fd); http_send_string(fd,"<center><p>ERROR 404</p></center>"); } free(fullpath); } }
int http_respond_file(int fd, struct http_request *r, char *response_type, char *filename) { struct stat st; int file_fd = open(filename, O_RDONLY); if (file_fd < 0) return http_respond_error(fd, r, 404); if (fstat(file_fd, &st) < 0) return http_respond_error(fd, r, 404); r->response_len = st.st_size; r->status_code = 200; strcpy(r->status_msg, "OK"); strcpy(r->response_type, response_type); if (http_send_header(fd, r) < 0) { close(file_fd); return -1; } sendfile(fd, file_fd, 0, r->response_len, 0); close(file_fd); return 0; }
int http_respond_error(int fd, struct http_request *r, int code) { r->response_len = 0; r->status_code = code; strcpy(r->status_msg, "NO"); strcpy(r->response_type, "text/html"); return http_send_header(fd, r); }
int cgi_parse_handler(epoll_cgi_t *cgi) { parse_cgi(cgi); if(http_send_header(cgi->con) == 0) { http_send_cgi_body(cgi); return 0; } return 1; }
/* * Reads an HTTP request from stream (fd), and writes an HTTP response * containing: * * 1) If user requested an existing file, respond with the file * 2) If user requested a directory and index.html exists in the directory, * send the index.html file. * 3) If user requested a directory and index.html doesn't exist, send a list * of files in the directory with links to each. * 4) Send a 404 Not Found response. */ void handle_files_request(int fd) { /* YOUR CODE HERE */ struct http_request *request = http_request_parse(fd); http_start_response(fd, 200); http_send_header(fd, "Content-type", "text/html"); http_end_headers(fd); http_send_string(fd, "<center><h1>Welcome to httpserver!</h1><hr><p>Nothing's here yet.</p></center>"); }
void http_func(struct connection *c) { /*setcstate(c, S_CONN);*/ /*set_timeout(c);*/ if (get_keepalive_socket(c)) { int p; if ((p = get_port(c->url)) == -1) { setcstate(c, S_INTERNAL); abort_connection(c); return; } make_connection(c, p, &c->sock1, http_send_header); } else http_send_header(c); }
/* * http_handle_get() * * Handle incoming get requests. Fall back to default handling if URL is not known */ int http_handle_get(http_conn* conn){ //Check conn->url for known uris int len = 0; bool isImage = false; const char * retval = httpResponseFunction(conn->uri, &len, &isImage); if (len > 0){ http_send_header(conn, len, HTTP_OK, isImage); //Send JSON reply send(conn->fd, (void*)retval, len, 0); return 0; } else { return http_find_file(conn); } }
int http_serve_file ( http_request *h, const gchar *docroot ) { gchar *path; guint fd, status; path = http_fix_path( h->uri, docroot ); fd = http_open_file( path, &status ); http_add_header( h, "Content-Type", http_mime_type( path ) ); http_send_header( h, status, fd == -1 ? "Not OK" : "OK" ); if ( fd != -1 ) http_sendfile( h, fd ); close(fd); g_free(path); return ( fd != -1 ); }
void http_page_send(int fd,char *fname) { char *r; int l ; FILE *f ; struct stat stbuf; stat(fname, &stbuf); l = stbuf.st_size; if (!S_ISREG(stbuf.st_mode)) { /* if Directory, add index and retry */ if (S_ISDIR(stbuf.st_mode)) { r = malloc(strlen(fname)+strlen(INDEXFILE)+10) ; if (r) { strcpy(r,fname); strcat(r,INDEXFILE); http_page_send(fd,r); free(r); return ; } } /* is not normal file... */ http_send_const(fd,NOTFOUNDMSG,404); return ; } f = fopen(fname,"rb"); if (!f) { http_send_const(fd,NOTFOUNDMSG,404); return ; } r = (char *)malloc(l); if (r) { fread(r,1,l,f); http_send_header(fd,l,200,"text/html"); write(fd,r,l); free(r); } else { http_send_const(1,SERVERERRMSG,501); } fclose(f); }
int http_serve_template ( http_request *h, gchar *file, GHashTable *data ) { gchar *form; guint r, n; form = parse_template( file, data ); n = strlen(form); http_add_header( h, "Content-Type", "text/html" ); http_send_header( h, 200, "OK" ); r = g_io_channel_write( h->sock, form, n, &n ); g_free( form ); if ( r != G_IO_ERROR_NONE ) { g_warning( "Serving template to %s failed: %m", h->peer_ip ); return 0; } return 1; }
int http_respond_string(int fd, struct http_request *r, char *response_type, char *response_fmt, ...) { va_list arglist; va_start(arglist, response_fmt); vsnprintf(r->response, HTTP_RESPONSE_LEN, response_fmt, arglist); va_end(arglist); r->response_len = strlen(r->response); r->status_code = 200; strcpy(r->status_msg, "OK"); strcpy(r->response_type, response_type); if (http_send_header(fd, r) < 0) return -1; return send(fd, r->response, r->response_len, 0); }
int cgi_info(http_socket *socket) { char buffer[256]; char str[16]; u8 *dat; int i, l; uart_puts("main::cgi_info()\r\n"); strcpy(buffer, "{\"model\":\"ecow-logic\","); strcat(buffer, "\"version\":\"0.2\","); dat = (u8 *)0x0003FE00; strcat(buffer, "\"ident\":["); for (i = 0; i < 16; i++) { l = b2ds(str, dat[i]); str[l] = 0; strcat(buffer, str); if (i != 15) strcat(buffer, ", "); } strcat(buffer, "], "); strcat(buffer, "\"fw_version\":[0,0,0,0]"); strcat(buffer, "}"); socket->content_len = strlen(buffer); http_send_header(socket, 200, HTTP_CONTENT_JSON); strcpy((char *)socket->tx, buffer); socket->tx_len += strlen(buffer); socket->state = HTTP_STATE_SEND; return 0; }
void http_send_redirect( http_request *h, gchar *dest ) { http_add_header ( h, "Location", dest ); http_send_header( h, 302, "Moved" ); }
void http_send_const(int sFd,char *str,int resultcode) { http_send_header(sFd,strlen(str),resultcode,"text/html"); write(sFd,str,strlen(str)); }
/* * http_handle_post() * * Process the post request and take the appropriate action. */ int http_handle_post(http_conn* conn) { int responseLen = 0; const char * postResponse = httpHandlePost(conn, &responseLen); if (responseLen != 0){ http_send_header(conn, responseLen, HTTP_OK, false); //Send JSON reply send(conn->fd, (void*)postResponse, responseLen, 0); conn->state = CLOSE; return 0; } //Fall through to old code if necessary char* tx_wr_pos = conn->tx_buffer; int ret_code = 0; struct upload_buf_struct *upload_buffer = &upload_buf; tx_wr_pos += sprintf(tx_wr_pos, HTTP_VERSION_STRING); tx_wr_pos += sprintf(tx_wr_pos, HTTP_NO_CONTENT_STRING); tx_wr_pos += sprintf(tx_wr_pos, HTTP_CLOSE); tx_wr_pos += sprintf(tx_wr_pos, HTTP_END_OF_HEADERS); if (!strcmp(conn->uri, mapping.name)) { send(conn->fd, conn->tx_buffer, (tx_wr_pos - conn->tx_buffer), 0); conn->state = CLOSE; mapping.func(); } else if (!strcmp(conn->uri, sweep_field.name)) { send(conn->fd, conn->tx_buffer, (tx_wr_pos - conn->tx_buffer), 0); conn->state = CLOSE; sweep_field.func(conn); } else if (!strcmp(conn->uri, lcd_field.name)) { send(conn->fd, conn->tx_buffer, (tx_wr_pos - conn->tx_buffer), 0); conn->state = CLOSE; lcd_field.func(conn); } else if (!strcmp(conn->uri, upload_field.name)) { conn->file_upload = 1; upload_buffer->rd_pos = upload_buffer->wr_pos = upload_buffer->buffer; memset(upload_buffer->rd_pos, '\0', conn->content_length ); upload_field.func(conn); } else if (!strcmp(conn->uri, flash_field.name)) { /* Kick off the flash programming. */ flash_field.func( conn ); } #ifdef RECONFIG_REQUEST_PIO_NAME else if (!strcmp(conn->uri, reset_field.name)) { /* Close the socket. */ send(conn->fd, conn->tx_buffer, (tx_wr_pos - conn->tx_buffer), 0); reset_field.func(); } #endif return ret_code; }
void* scheduler_code(void* data) { printf("scheduler_thread running\n"); signal(SIGUSR2, cleanup_scheduler); sigset_t set; sigemptyset(&set); sigaddset(&set, SIGUSR2); scheduler_data* param = (scheduler_data*) data; buffer* buf = param->buffer; sem_t *sem_buffer_empty = param->sem_buffer_empty; sem_t *sem_buffer_full = param->sem_buffer_full; pthread_mutex_t *buffer_mutex = param->buffer_mutex; char debug_str[100]; sprintf(debug_str, "config policy: %d\n", param->policy); utils_debug(debug_str); while (true) { sigprocmask(SIG_UNBLOCK, &set, NULL); sem_wait(sem_buffer_empty); // only remove if buffer is not empty sigprocmask(SIG_BLOCK, &set, NULL); //block_signals(); pthread_mutex_lock(buffer_mutex); printf("On Scheduler: New Request\n"); buffer_node* node = buf->first->next; buffer_node* parent = buf->first; buffer_node* best = NULL; buffer_node* parentbest = NULL; if (param->policy == FIFO_POLICY) { best = node; parentbest = parent; } else { while (node != NULL) { //printf("on buffer iteration: request type %s\n", node->request->type == STATIC_PAGE ? "STATIC_PAGE" : "DYNAMIC_SCRIPT" ); if ((param->policy == STATIC_POLICY && node->request->type == STATIC_PAGE) || (param->policy == DYNAMIC_POLICY && node->request->type == DYNAMIC_SCRIPT)) { parentbest = parent; best = node; break; } else if(best == NULL) { parentbest = parent; best = node; } if (node->next != NULL) { parent = parent->next; node = node->next; } else { break; } } } printf("On Scheduler: Found request\n"); printf("On Scheduler: request type %s\n", best->request->type == STATIC_PAGE ? "STATIC_PAGE" : "DYNAMIC_SCRIPT" ); printf("On Scheduler: work with name: %s\n\n", best->request->name); parentbest->next = best->next; buf->cur_size--; pthread_mutex_unlock(buffer_mutex); sem_post(sem_buffer_full); //sleep(1); if (best->request->type == DYNAMIC_SCRIPT) { utils_debug("New dynamic script: "); printf("%s\n", best->request->name); int script_allowed = 0; int u; for (u = 0; u < param->n_scripts; u++) { if (!strcmp(param->scripts[u], best->request->name)) { script_allowed = 1; } } if (!script_allowed) { printf("%s\n", best->request->name); utils_debug("This script is not allowed.\n"); // TODO Michel este script nao pode ser corrido, que se faz char error[] = "Script not allowed.<br>"; http_send_header(best->request->socket, "text/html"); send(best->request->socket, error, strlen(error), 0); close(best->request->socket); continue; } } int i; for (i = 0; i < param->n_threads; i++) { pthread_mutex_lock(¶m->thread_locks[i]); if (param->thread_ready[i] == 1) { param->requests[i] = best->request; param->thread_ready[i] = 0; pthread_mutex_unlock(¶m->thread_locks[i]); pthread_cond_broadcast(&(param->wait_for_work[i])); break; } pthread_mutex_unlock(¶m->thread_locks[i]); } if (i >= param->n_threads) { printf("No worker available.\n"); // This might happen if the workers are slow, because when the request is delivered to a worker we remove the request from the buffer, leaving space for more requests, but no thread available. char error[] = "<!DOCTYPE html>\n <head></head>\n <body> <h2>Server error. No processing units available. </h2> </body>\n\n"; send(best->request->socket, error, strlen(error), 0); close(best->request->socket); } else { printf("Delivered work to worker %d\n\n", i); } } }
int cgi_ng_page(http_socket *socket) { fs_entry entry; char page_name[9]; char *pnt; u32 offset; int found; int type; int l; int i; if (socket->content_len == 0) { pnt = (char *)socket->uri; /* If the URI start with "/p/" this is a page request */ if (strncmp(pnt, "/p/", 3) == 0) { pnt += 3; for (i = 0; i < 8; i++) { if ((pnt[i] == ' ') || (pnt[i] == 0x0D) ) break; page_name[i] = pnt[i]; } page_name[i] = 0; } /* Else, use the homepage */ else strcpy(page_name, "home.htm"); found = 0; for (i = 0; i < 128; i++) { if ( ! fs_getentry(i, &entry)) break; if (strcmp(page_name, entry.name) == 0) { found = 1; break; } } if ( ! found) { socket->state = HTTP_STATE_NOT_FOUND; return(0); } socket->content_len = entry.size; socket->content_priv = (void *)i; type = HTTP_CONTENT_PLAIN; l = strlen(entry.name); if (l >= 4) { pnt = entry.name; pnt += (l - 4); if (strcmp(pnt, ".htm") == 0) type = HTTP_CONTENT_HTML; if (strcmp(pnt, ".png") == 0) type = HTTP_CONTENT_PNG; if (strcmp(pnt, ".css") == 0) type = HTTP_CONTENT_CSS; if (strcmp(pnt, ".jpg") == 0) type = HTTP_CONTENT_CSS; } http_send_header(socket, 200, type); } else { i = (int)socket->content_priv; fs_getentry(i, &entry); } i = socket->content_len; if (i > 768) i = 768; offset = entry.start; offset += (entry.size - socket->content_len); flash_read(offset, (u8 *)socket->tx, i); socket->tx_len += i; socket->content_len -= i; if (socket->content_len == 0) socket->state = HTTP_STATE_SEND; else socket->state = HTTP_STATE_SEND_MORE; return(0); }
int cgi_ng_pld(http_socket *socket) { u32 content_length; char *file; int mph_len; char *pnt; int len; int i; if (socket->content_priv == 0) { uart_puts("CGI: Start loading PLD.\r\n"); pld_init(); for (i = 0; i < 7500; i++) ; pld_load_start(); pnt = 0; for (i = 0; i < 16; i++) { char arg[16]; pnt = http_get_header(socket, pnt); if (pnt == 0) break; if (strncmp(pnt, "Content-Length:", 15) == 0) { pnt += 16; for (i = 0; i < 7; i++) { if ( (*pnt < '0') || (*pnt > '9') ) break; arg[i] = *pnt; pnt++; } arg[i] = 0; content_length = atoi(arg); break; } } pnt = (char *)socket->rx; while(pnt != 0) { if ( (pnt[0] == 0x0d) && (pnt[1] == 0x0a) && (pnt[2] == 0x0d) && (pnt[3] == 0x0a) ) { /* Get a pointer on datas (after multipart header) */ file = (pnt + 4); break; } /* Search the next CR */ pnt = strchr(pnt + 1, 0x0d); } /* Multipart header length */ mph_len = ((u32)file - (u32)socket->rx); /* Received length */ len = socket->rx_len - mph_len; pld_load((const u8 *)file, len); if (len < content_length) socket->state = HTTP_STATE_RECV_MORE; socket->content_priv = (void *)(content_length - mph_len - len); } else { content_length = (u32)socket->content_priv; pld_load((u8 *)socket->rx, socket->rx_len); if (socket->rx_len < content_length) { socket->content_priv = (void *)(content_length - socket->rx_len); } else { uart_puts("CGI: PLD bitstream loaded !\r\n"); pld_load_end(); socket->content_priv = 0; http_send_header(socket, 200, 0); socket->state = HTTP_STATE_SEND; } } return(0); }