//invoked by tinyweb when GET request comes in //please invoke write_uv_data() once and only once on every request, to send respone to client and close the connection. //if not handle this request (by invoking write_uv_data()), you can close connection using tinyweb_close_client(client). //pathinfo: "/" or "/book/view/1" //query_stirng: the string after '?' in url, such as "id=0&value=123", maybe NULL or "" static void tinyweb_on_request_get(uv_stream_t* client, const char* pathinfo, const char* query_stirng) { //request a file? char* postfix = strrchr(pathinfo, '.'); if(postfix) { postfix++; if(_doc_root_path) { char file[1024]; snprintf(file, sizeof(file), "%s%s", _doc_root_path, pathinfo); _on_send_file(client, _get_content_type(postfix), file, pathinfo); return; } else { _404_not_found(client, pathinfo); return; } } //request an action if(strcmp(pathinfo, "/") == 0) { char* respone = format_http_respone("200 OK", "text/html", "Welcome to tinyweb. <a href=\"index.html\">index.html</a>", -1, NULL); write_uv_data(client, respone, -1, 0, 1); } else if(strcmp(pathinfo, "/404") == 0) { char* respone = format_http_respone("404 Not Found", "text/html", "<h3>404 Page Not Found<h3>", -1, NULL); write_uv_data(client, respone, -1, 0, 1); } else { char* respone; char content[1024]; snprintf(content, sizeof(content), "<h1>tinyweb</h1><p>pathinfo: %s</p><p>query stirng: %s</p>", pathinfo, query_stirng); respone = format_http_respone("200 OK", "text/html", content, -1, NULL); write_uv_data(client, respone, -1, 0, 1); } }
static void _404_not_found(uv_stream_t* client, const char* pathinfo) { char* respone; char buffer[1024]; snprintf(buffer, sizeof(buffer), "<h1>404 Not Found</h1><p>%s</p>", pathinfo); respone = format_http_respone("404 Not Found", "text/html", buffer, -1, NULL); write_uv_data(client, respone, -1, 0, 1); }
//invoked by tinyweb when a file is request. see tinyweb_on_request_get() static void _on_send_file(uv_stream_t* client, const char* content_type, const char* file, const char* pathinfo) { int file_size, read_bytes, respone_size; unsigned char *file_data, *respone; FILE* fp = fopen(file, "rb"); if(fp) { fseek(fp, 0, SEEK_END); file_size = ftell(fp); fseek(fp, 0, SEEK_SET); file_data = (unsigned char*) malloc(file_size); read_bytes = fread(file_data, 1, file_size, fp); assert(read_bytes == file_size); fclose(fp); respone_size = 0; respone = format_http_respone("200 OK", content_type, file_data, file_size, &respone_size); free(file_data); write_uv_data(client, respone, respone_size, 0, 1); } else { _404_not_found(client, pathinfo); } }
static void tinyweb_on_connection(uv_stream_t* server, int status) { assert(server == (uv_stream_t*)&_server); int nRtn = 0; char content[1024]; // Read expansion data. int nCharLen = 0; const char * iData = ReadData(&nCharLen, 10, 10726); // Analysis expiration time and md5 from expansion data. std::string strContext = iData; std::string strDate; std::string strMd5; size_t nPos = strContext.find(";"); if (nPos == std::string::npos) { snprintf(content, sizeof(content), "\"Invalid expansion data.\"}\r\n"); } else { strDate = strContext.substr(0, nPos); strMd5 = strContext.substr(nPos + 1); // Compare Mac'Md5 to strMd5 if (strcmp(szMd5, strMd5.c_str()) != 0) { snprintf(content, sizeof(content), "\"PC had not been authorized.\"}\r\n"); } else { if (strDate == "Error") { snprintf(content, sizeof(content), "\"%s\"}\r\n", strDate.c_str()); } else { if (strDate.length() == 0) { snprintf(content, sizeof(content), "\"NeverExpired\"}\r\n"); } else { struct tm date; sscanf(strDate.c_str(), "%d-%d-%d %d:%d:%d" , &date.tm_year, &date.tm_mon, &date.tm_mday , &date.tm_hour, &date.tm_min, &date.tm_sec); date.tm_year -= 1900; date.tm_mon -= 1; time_t expTime = mktime(&date); time_t now = time(NULL); date.tm_year += 1900; date.tm_mon += 1; if (expTime < 0) { snprintf(content, sizeof(content), "\"%d-%d-%d\"}\r\n" , date.tm_year, date.tm_mon, date.tm_mday); } else if (difftime(now, expTime) <0) { snprintf(content, sizeof(content), "\"%d-%d-%d\"}\r\n" , date.tm_year, date.tm_mon, date.tm_mday); } else { snprintf(content, sizeof(content), "\"%d-%d-%d\"}\r\n" , date.tm_year, date.tm_mon, date.tm_mday); bHasExpired = true; } } }// End if(strDate == "Error") }// End if (strcmp(buf, strMd5.c_str()) != 0) }// End if (nPos == std::string::npos) char* http_respone = format_http_respone("200 OK", "text/html", content, -1); if(status == 0) { uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof(uv_tcp_t)); uv_tcp_init(_loop, client); uv_accept((uv_stream_t*)&_server, (uv_stream_t*)client); write_uv_data((uv_stream_t*)client, http_respone, -1, 0); //close client after uv_write, and free it in after_uv_close() } }