// This is called to process a file upload request. void Webserver::StartUpload(HttpSession& session, const char* fileName, uint32_t fileLength, time_t lastModified) { CancelUpload(session); if (uploadIp != 0) { session.uploadState = uploadBusy; // upload buffer already in use } else { FileStore *file = platform->GetFileStore(FS_PREFIX, fileName, true); if (file == nullptr) { session.uploadState = cantCreate; } else { session.fileBeingUploaded.Set(file); strncpy(session.filenameBeingUploaded, fileName, FILENAME_LENGTH); session.fileLastModified = lastModified; session.postLength = fileLength; session.bytesWritten = 0; session.nextFragment = 1; session.uploadState = uploading; session.bufNumber = 0; session.bufPointer = 0; uploadIp = session.ip; } } }
// Get the Json response for this command. // 'value' is null-terminated, but we also pass its length in case it contains embedded nulls, which matter when uploading files. bool Webserver::GetJsonResponse(const char* request, const char* key, const char* value, size_t valueLength) { bool found = true; // assume success bool keepOpen = false; // assume we don't want to persist the connection if (StringEquals(request, "status")) // new style status request { GetStatusResponse(1); } else if (StringEquals(request, "poll")) // old style status request { GetStatusResponse(0); } else if (StringEquals(request, "gcode") && StringEquals(key, "gcode")) { LoadGcodeBuffer(value); snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"buff\":%u}", GetReportedGcodeBufferSpace()); } else if (StringEquals(request, "upload_begin") && StringEquals(key, "name")) { CancelUpload(); FileStore *f = platform->GetFileStore("0:/", value, true); if (f != NULL) { fileBeingUploaded.Set(f); uploadState = uploadOK; } else { uploadState = uploadError; } GetJsonUploadResponse(); } else if (StringEquals(request, "upload_data") && StringEquals(key, "data")) { if (uploadState == uploadOK) { uploadPointer = value; uploadLength = valueLength; } GetJsonUploadResponse(); keepOpen = true; } else if (StringEquals(request, "upload_end") && StringEquals(key, "size")) { // Write the remaining data if (uploadLength != 0) { if (!fileBeingUploaded.Write(uploadPointer, uploadLength)) { uploadState = uploadError; } } uploadPointer = NULL; uploadLength = 0; if (uploadState == uploadOK && !fileBeingUploaded.Flush()) { uploadState = uploadError; } // Check the file length is as expected if (uploadState == uploadOK && fileBeingUploaded.Length() != strtoul(value, NULL, 10)) { uploadState = uploadError; } // Close the file if (!fileBeingUploaded.Close()) { uploadState = uploadError; } GetJsonUploadResponse(); if (uploadState != uploadOK && strlen(filenameBeingUploaded) != 0) { platform->GetMassStorage()->Delete("0:/", filenameBeingUploaded); } filenameBeingUploaded[0] = 0; } else if (StringEquals(request, "upload_cancel")) { CancelUpload(); snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"err\":%d}", 0); } else if (StringEquals(request, "delete") && StringEquals(key, "name")) { bool ok = platform->GetMassStorage()->Delete("0:/", value); snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"err\":%d}", (ok) ? 0 : 1); } else if (StringEquals(request, "files")) { const char* dir = (StringEquals(key, "dir")) ? value : platform->GetGCodeDir(); const char* fileList = platform->GetMassStorage()->FileList(dir, false); snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"files\":[%s]}", fileList); } else if (StringEquals(request, "fileinfo") && StringEquals(key, "name")) { unsigned long length; float height, filament, layerHeight; char generatedBy[50]; bool found = GetFileInfo(value, length, height, filament, layerHeight, generatedBy, ARRAY_SIZE(generatedBy)); if (found) { snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"err\":0,\"size\":%lu,\"height\":%.2f,\"filament\":%.1f,\"layerHeight\":%.2f,\"generatedBy\":\"%s\"}", length, height, filament, layerHeight, generatedBy); } else { snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"err\":1}"); } } else if (StringEquals(request, "name")) { snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"myName\":\""); size_t j = strlen(jsonResponse); for (size_t i = 0; i < ARRAY_SIZE(myName) - 1; ++i) { char c = myName[i]; if (c < ' ') // if null terminator or bad character break; if (c == '"' || c == '\\') { // Need to escape the quote-mark or backslash for JSON jsonResponse[j++] = '\\'; } jsonResponse[j++] = c; } jsonResponse[j++] = '"'; jsonResponse[j++] = '}'; jsonResponse[j] = 0; } else if (StringEquals(request, "password") && StringEquals(key, "password")) { CheckPassword(value); snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"password\":\"%s\"}", (gotPassword) ? "right" : "wrong"); } else if (StringEquals(request, "axes")) { strncpy(jsonResponse, "{\"axes\":", ARRAY_UPB(jsonResponse)); char ch = '['; for (int8_t drive = 0; drive < AXES; drive++) { sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "%c%.1f", ch, platform->AxisTotalLength(drive)); ch = ','; } strncat(jsonResponse, "]}", ARRAY_UPB(jsonResponse)); } else if (StringEquals(request, "connect")) { CancelUpload(); GetStatusResponse(1); } else { found = false; } JsonReport(found, request); return keepOpen; }