/* * This will handle connection for each client * */ void *client_handler(void *socketDescriptor){ // Get the socket descriptor int newSocket = *(int*) socketDescriptor; int readSize; char *message, *realMessage, clientMessage[2000]; int quit; struct message_s recv_message, send_message; int connected, authenticated; FILE *fb; char target_filename[1024]; char directory[1024 + 10]; authenticated = 0; connected = 0; quit = 0; while (quit == 0){ // Get message from client memset(recv_message.payload, '\0', 1024); readSize = recv(newSocket, (char *)&recv_message, sizeof(struct message_s), 0); // Print type, for debugging printf("recv_message.type is %x\n", recv_message.type); // Analyze message switch( recv_message.type ){ /******************************** * Handle OPEN_CONN_REQUEST * ********************************/ case (char) 0xA1: printf("Server - OPEN_CONN_REQUEST received\n"); send_open_conn_reply(newSocket); printf("Server - OPEN_CONN_REPLY sent\n"); connected = 1; break; /******************************** * Handle AUTH_REQUEST * ********************************/ case (char) 0xA3: printf("Server - AUTH_REQUEST received\n"); recv_message.payload[recv_message.length-5] = '\0'; printf("Server - Authenticating: %s\n",recv_message.payload); authenticated = check_auth(recv_message.payload); send_auth_reply(newSocket, check_auth(recv_message.payload)); printf("Server - AUTH_REPLY sent\n"); if( authenticated == 1) printf("\t(Server - Access Granted)\n"); else printf("\t(Server - Access Failed)\n"); break; /******************************** * Handle LIST_REQUEST * ********************************/ case (char) 0xA5: printf("Server - LIST_REQUEST received\n"); if (authenticated) { list_dir_send_list_reply(newSocket); printf("Server - LIST_REPLY sent\n"); } else { strcpy(send_message.payload, "Server - You are not authenticated!\n"); send_message.length = 12 + strlen(send_message.payload); while( send(newSocket, (char*)(&send_message),send_message.length, 0) != send_message.length ); } break; /******************************** * Handle GET_REQUEST * ********************************/ case (char) 0xA7: if (authenticated) { strncpy(target_filename, recv_message.payload,recv_message.length-12); target_filename[recv_message.length-12] = '\0'; printf("target filename: %s\n", target_filename); printf("GET_REQUEST: %s\n", recv_message.payload); strcpy(directory, "./filedir/"); strcat(directory, target_filename); if(fb = fopen(directory, "rb"), fb != NULL){ printf("Server - File found.\n"); printf("directory: %s\n", directory); send_get_reply(newSocket, 1); printf("GET_REPLY Sent!\n"); sleep(1); send_file_data(newSocket, fb); fclose(fb); } else { printf("Error: Server - File does not exist.\n"); send_get_reply(newSocket, 0); printf("GET_REPLY Sent\n"); } } else { strcpy(send_message.payload, "Server - You are not authenticated!\n"); send_message.length = 12 + strlen(send_message.payload); while( send(newSocket, (char*)(&send_message),send_message.length, 0) != send_message.length ); } break; /******************************** * Handle PUT_REQUEST * ********************************/ case (char) 0xA9: if (authenticated){ strncpy(target_filename, recv_message.payload,recv_message.length-12); target_filename[recv_message.length-12] = '\0'; printf("target filename: %s\n", target_filename); printf("PUT_REQUEST: %s\n", recv_message.payload); printf("PUT_REQUEST Received\n"); strcpy(directory, "./filedir/"); strcat(directory, target_filename); memset(send_message.payload, '\0', 1024); send_message.protocol[0] = 0xe3; strcat(send_message.protocol, "myftp"); send_message.type = 0xAA; send_message.length = 12; send(newSocket, (char*)(&send_message), send_message.length, 0); printf("PUT_REPLY Sent\n"); recv_file_data(newSocket, directory); } else { strcpy(send_message.payload, "Server - You are not authenticated!\n"); send_message.length = 12 + strlen(send_message.payload); while( send(newSocket, (char*)(&send_message),send_message.length, 0) != send_message.length ); } break; /******************************** * Handle QUIT_REQUEST * ********************************/ case (char) 0xAB: printf("Disconnecting by request. (socket: %d)\n", newSocket); send_message.protocol[0] = 0xe3; strcat(send_message.protocol, "myftp"); send_message.type = 0xAC; send_message.length = 12; while( send(newSocket, (char*)(&send_message),send_message.length, 0) !=12 ); close(newSocket); quit = 1; break; /* Invalid Protocol */ default: printf("Error: Server - Invalid Protocol Received"); quit = 1; break; } } puts("Client disconnected"); fflush(stdout); // Free the socket pointer free(socketDescriptor); printf("ending thread\n"); pthread_exit(NULL); }
/* Example multipart form-data request content format: --AaB03x Content-Disposition: form-data; name="submit-name" Larry --AaB03x Content-Disposition: form-data; name="file"; filename="file1.txt" Content-Type: text/plain ... contents of file1.txt ... --AaB03x-- */ static evhtp_res upload_read_cb (evhtp_request_t *req, evbuf_t *buf, void *arg) { RecvFSM *fsm = arg; char *line; size_t len; gboolean no_line = FALSE; int res = EVHTP_RES_OK; if (fsm->state == RECV_ERROR) return EVHTP_RES_OK; /* Update upload progress. */ fsm->progress->uploaded += (gint64)evbuffer_get_length(buf); seaf_debug ("progress: %lld/%lld\n", fsm->progress->uploaded, fsm->progress->size); evbuffer_add_buffer (fsm->line, buf); /* Drain the buffer so that evhtp don't copy it to another buffer * after this callback returns. */ evbuffer_drain (buf, evbuffer_get_length (buf)); while (!no_line) { switch (fsm->state) { case RECV_INIT: line = evbuffer_readln (fsm->line, &len, EVBUFFER_EOL_CRLF_STRICT); if (line != NULL) { seaf_debug ("[upload] boundary line: %s.\n", line); if (!strstr (line, fsm->boundary)) { seaf_warning ("[upload] no boundary found in the first line.\n"); free (line); res = EVHTP_RES_BADREQ; goto out; } else { fsm->state = RECV_HEADERS; free (line); } } else { no_line = TRUE; } break; case RECV_HEADERS: line = evbuffer_readln (fsm->line, &len, EVBUFFER_EOL_CRLF_STRICT); if (line != NULL) { seaf_debug ("[upload] mime header line: %s.\n", line); if (len == 0) { /* Read an blank line, headers end. */ free (line); if (g_strcmp0 (fsm->input_name, "file") == 0) { if (open_temp_file (fsm) < 0) { seaf_warning ("[upload] Failed open temp file.\n"); res = EVHTP_RES_SERVERR; goto out; } } seaf_debug ("[upload] Start to recv %s.\n", fsm->input_name); fsm->state = RECV_CONTENT; } else if (parse_mime_header (line, fsm) < 0) { free (line); res = EVHTP_RES_BADREQ; goto out; } else { free (line); } } else { no_line = TRUE; } break; case RECV_CONTENT: if (g_strcmp0 (fsm->input_name, "file") == 0) res = recv_file_data (fsm, &no_line); else res = recv_form_field (fsm, &no_line); if (res != EVHTP_RES_OK) goto out; break; } } out: if (res != EVHTP_RES_OK) { /* Don't receive any data before the connection is closed. */ evhtp_request_pause (req); /* Set keepalive to 0. This will cause evhtp to close the * connection after sending the reply. */ req->keepalive = 0; fsm->state = RECV_ERROR; } if (res == EVHTP_RES_BADREQ) { evhtp_send_reply (req, EVHTP_RES_BADREQ); } else if (res == EVHTP_RES_SERVERR) { evbuffer_add_printf (req->buffer_out, "Internal server error\n"); evhtp_send_reply (req, EVHTP_RES_SERVERR); } return EVHTP_RES_OK; }