Merge remote-tracking branch 'origin/master'
# Conflicts: # main.cpp # netlib
This commit is contained in:
commit
2b77a349fa
2 changed files with 111 additions and 138 deletions
74
main.cpp
74
main.cpp
|
@ -126,6 +126,16 @@ std::map<std::string, std::string> parse_headers(const std::vector<std::string>
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string filename_sanitation(std::string filename)
|
||||||
|
{
|
||||||
|
std::filesystem::path p(filename);
|
||||||
|
std::string ret = p.filename().string();
|
||||||
|
if (ret == "" || ret == "." || ret == "..")
|
||||||
|
return "generic_file.txt";
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
std::string get_filename(std::string data)
|
std::string get_filename(std::string data)
|
||||||
{
|
{
|
||||||
bool started_quote = false;
|
bool started_quote = false;
|
||||||
|
@ -139,6 +149,7 @@ std::string get_filename(std::string data)
|
||||||
else if (started_quote)
|
else if (started_quote)
|
||||||
ret.push_back(x);
|
ret.push_back(x);
|
||||||
}
|
}
|
||||||
|
ret = filename_sanitation(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,15 +192,62 @@ char *search_substring(char *start_data, const char *substring, size_t size)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isNumber(std::string a)
|
||||||
|
{
|
||||||
|
if (a.empty())
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < a.length(); i++)
|
||||||
|
{
|
||||||
|
if (isdigit(a[i]) == 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check_ip(const char* ip)
|
||||||
|
{
|
||||||
|
std::string buff;
|
||||||
|
std::vector<std::string> tokens;
|
||||||
|
if (strcmp(ip, "localhost") == 0)
|
||||||
|
return true;
|
||||||
|
buff = ip;
|
||||||
|
tokens = split(ip, ".");
|
||||||
|
if (tokens.size() != 4)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < tokens.size(); i++)
|
||||||
|
{
|
||||||
|
if (isNumber(tokens[i]) == false)
|
||||||
|
return false;
|
||||||
|
else if (atoi(tokens[i].c_str()) > 255)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> load_whitelist(const std::string &filename)
|
||||||
|
{
|
||||||
|
std::vector<std::string> ret;
|
||||||
|
std::ifstream file(filename);
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(file, line))
|
||||||
|
{
|
||||||
|
if (check_ip(line.c_str()))
|
||||||
|
ret.push_back(line);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
netlib::server_raw server(false, 0);
|
netlib::server_raw server(15000000);
|
||||||
server.open_server("0.0.0.0", 8080);
|
server.open_server("0.0.0.0", 8080);
|
||||||
|
std::vector<std::string> whitelist = load_whitelist("whitelist.txt");
|
||||||
|
server.add_whitelist(whitelist);
|
||||||
|
std::println("{} ips found in whitelist", whitelist.size());
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
std::vector<int> readable = server.wait_readable();
|
std::vector<int> readable = server.wait_readable();
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
//std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
for (auto user: readable)
|
for (auto user: readable)
|
||||||
{
|
{
|
||||||
char * data = server.get_line(user);
|
char * data = server.get_line(user);
|
||||||
|
@ -243,6 +301,8 @@ int main()
|
||||||
else if (h.contains("Content-Length:"))
|
else if (h.contains("Content-Length:"))
|
||||||
{
|
{
|
||||||
file_size = atoi_newline(h["Content-Length:"].c_str());
|
file_size = atoi_newline(h["Content-Length:"].c_str());
|
||||||
|
if (file_size > 1000000000) //1GB
|
||||||
|
server.disconnect_user(user);
|
||||||
}
|
}
|
||||||
else if (line_str.contains(boundary) && boundary.contains("----"))
|
else if (line_str.contains(boundary) && boundary.contains("----"))
|
||||||
{
|
{
|
||||||
|
@ -266,8 +326,8 @@ int main()
|
||||||
std::string filename = get_filename(file_.back());
|
std::string filename = get_filename(file_.back());
|
||||||
int size_to_get = line_str.size() + line_str2.size() + line_str3.size() + line_str4.size();
|
int size_to_get = line_str.size() + line_str2.size() + line_str3.size() + line_str4.size();
|
||||||
size_to_get = file_size - size_to_get;
|
size_to_get = file_size - size_to_get;
|
||||||
int chunks_to_get = (size_to_get / 2048) + 1;
|
int chunks_to_get = (size_to_get / 8198) + 1;
|
||||||
int last_chunk_size = size_to_get % 2048;
|
int last_chunk_size = size_to_get % 8198;
|
||||||
while (chunks_to_get > 0)
|
while (chunks_to_get > 0)
|
||||||
{
|
{
|
||||||
if (chunks_to_get == 1)
|
if (chunks_to_get == 1)
|
||||||
|
@ -280,8 +340,8 @@ int main()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *chunk = server.receive_data_ensured(user, 2048);
|
char *chunk = server.receive_data_ensured(user, 8198);
|
||||||
write_file_size(filename, chunk, 2048);
|
write_file_size(filename, chunk, 8198);
|
||||||
free(chunk);
|
free(chunk);
|
||||||
}
|
}
|
||||||
chunks_to_get--;
|
chunks_to_get--;
|
||||||
|
|
175
test.html
175
test.html
|
@ -1,177 +1,90 @@
|
||||||
//THIS IS NOT MY CODE, THIS IS AN AI GENERATED CODE TO TEST MY SERVER AND SEE HOW EVERYTHING WORKS
|
|
||||||
//I WILL CHANGE IT TO MY OWN WHEN MY SERVER WORKS PROPERLY
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<title>Sube musica</title>
|
||||||
<title>Drag and Drop File Upload</title>
|
|
||||||
<style>
|
<style>
|
||||||
#drop_zone {
|
#drop_zone
|
||||||
border: 5px dashed blue; /* Dashed looks more like a typical drop zone */
|
{
|
||||||
width: 300px;
|
width: 600px;
|
||||||
height: 150px;
|
height: 500px;
|
||||||
padding: 20px;
|
border: 2px solid #ccc;
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-family: sans-serif;
|
color: #777;
|
||||||
line-height: 1.5;
|
font-size: 1.2em;
|
||||||
transition: border-color 0.3s, background-color 0.3s; /* Add smooth transition */
|
margin-bottom: 20px;
|
||||||
}
|
background-color: #fff;
|
||||||
#drop_zone.dragover { /* Style when dragging over */
|
transition: background-color 0.3s, border-color 0.3s;
|
||||||
border-color: green;
|
|
||||||
background-color: #e0ffe0;
|
|
||||||
}
|
|
||||||
#status {
|
|
||||||
margin-top: 15px;
|
|
||||||
font-family: sans-serif;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<h1>Simple File Upload via Drag & Drop</h1>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
id="drop_zone"
|
id="drop_zone"
|
||||||
ondrop="dropHandler(event);"
|
ondrop="dropHandler(event);"
|
||||||
ondragover="dragOverHandler(event);"
|
ondragover="dragOverHandler(event);"
|
||||||
ondragenter="dragEnterHandler(event);" /* Optional: visual feedback on enter */
|
ondragenter="dragEnterHandler(event);"
|
||||||
ondragleave="dragLeaveHandler(event);" /* Optional: visual feedback on leave */
|
|
||||||
>
|
>
|
||||||
<p>Drag one or more files to this <i>drop zone</i>.</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="status"></div> <!-- To display upload status -->
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const dropZone = document.getElementById('drop_zone');
|
const dropZone = document.getElementById('drop_zone');
|
||||||
const statusDiv = document.getElementById('status');
|
|
||||||
|
|
||||||
function dropHandler(ev) {
|
function dropHandler(ev)
|
||||||
console.log("File(s) dropped");
|
{
|
||||||
statusDiv.textContent = 'Processing dropped file(s)...';
|
|
||||||
dropZone.classList.remove('dragover'); // Remove highlight style
|
|
||||||
|
|
||||||
// Prevent default behavior (Prevent file from being opened)
|
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
|
||||||
let filesToUpload = []; // Store files to potentially upload
|
let file_to_upload;
|
||||||
|
|
||||||
if (ev.dataTransfer.items) {
|
if (ev.dataTransfer.items) {
|
||||||
// Use DataTransferItemList interface to access the file(s)
|
[...ev.dataTransfer.items].forEach((item, i) =>
|
||||||
[...ev.dataTransfer.items].forEach((item, i) => {
|
{
|
||||||
// If dropped items aren't files, reject them
|
if (item.kind === "file")
|
||||||
if (item.kind === "file") {
|
file_to_upload = item.getAsFile();
|
||||||
const file = item.getAsFile();
|
|
||||||
if (file) { // Check if getAsFile() returned a file
|
|
||||||
console.log(`… file[${i}].name = ${file.name}`);
|
|
||||||
filesToUpload.push(file); // Add file to our list
|
|
||||||
} else {
|
|
||||||
console.log(`… item[${i}] is a file but couldn't be accessed (perhaps a directory?).`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log(`… item[${i}].kind = ${item.kind} (not a file)`);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
// Use DataTransfer interface to access the file(s)
|
}
|
||||||
[...ev.dataTransfer.files].forEach((file, i) => {
|
else
|
||||||
console.log(`… file[${i}].name = ${file.name}`);
|
{
|
||||||
filesToUpload.push(file); // Add file to our list
|
|
||||||
|
[...ev.dataTransfer.files].forEach((file, i) =>
|
||||||
|
{
|
||||||
|
file_to_upload = file;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- UPLOAD THE FILE(S) ---
|
uploadFile(file_to_upload);
|
||||||
if (filesToUpload.length > 0) {
|
|
||||||
statusDiv.textContent = `Found ${filesToUpload.length} file(s). Uploading...`;
|
|
||||||
// Example: Uploading the first file found
|
|
||||||
// uploadFile(filesToUpload[0]);
|
|
||||||
|
|
||||||
// OR: Upload ALL dropped files sequentially
|
|
||||||
// (You might want more advanced logic for parallel uploads or progress bars)
|
|
||||||
filesToUpload.forEach(uploadFile);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
console.log("No valid files found to upload.");
|
|
||||||
statusDiv.textContent = 'No valid files detected in drop.';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function dragOverHandler(ev) {
|
function dragOverHandler(ev)
|
||||||
// Prevent default behavior (Prevent file from being opened)
|
{
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
// Optional: Visual feedback
|
|
||||||
// dropZone.classList.add('dragover'); // Handled by dragenter now
|
|
||||||
}
|
}
|
||||||
|
function dragEnterHandler(ev)
|
||||||
function dragEnterHandler(ev) {
|
{
|
||||||
// Optional visual feedback
|
ev.preventDefault();
|
||||||
console.log("File entered drop zone");
|
|
||||||
dropZone.classList.add('dragover');
|
|
||||||
ev.preventDefault(); // Necessary for drop event to fire correctly in some browsers
|
|
||||||
}
|
|
||||||
|
|
||||||
function dragLeaveHandler(ev) {
|
|
||||||
// Optional visual feedback
|
|
||||||
console.log("File left drop zone");
|
|
||||||
// Ensure it only removes class if leaving the drop_zone itself, not child elements
|
|
||||||
if (ev.target === dropZone) {
|
|
||||||
dropZone.classList.remove('dragover');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// --- Handles the actual upload ---
|
function uploadFile(file)
|
||||||
function uploadFile(file) {
|
{
|
||||||
// V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V
|
|
||||||
// IMPORTANT: Replace this URL with your actual server endpoint!
|
const url = '/';
|
||||||
const url = '/your-server-upload-endpoint';
|
|
||||||
// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
|
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
|
||||||
// 'uploadedFile' is the name the server will look for.
|
|
||||||
// You might need to change this depending on your server-side code.
|
|
||||||
formData.append('uploadedFile', file, file.name);
|
formData.append('uploadedFile', file, file.name);
|
||||||
|
|
||||||
console.log(`Uploading ${file.name} to ${url}`);
|
fetch(url,
|
||||||
statusDiv.textContent = `Uploading ${file.name}...`; // Update status
|
{
|
||||||
|
method: 'POST',
|
||||||
fetch(url, {
|
|
||||||
method: 'POST', // Or 'PUT' depending on your server API
|
|
||||||
body: formData,
|
body: formData,
|
||||||
// Headers are often not needed for FormData uploads,
|
|
||||||
// the browser sets the 'Content-Type' to 'multipart/form-data' automatically.
|
|
||||||
})
|
})
|
||||||
.then(response => {
|
|
||||||
if (!response.ok) {
|
|
||||||
// Throw an error if the server response is not 2xx
|
|
||||||
// Try to get error message from body if possible
|
|
||||||
return response.text().then(text => {
|
|
||||||
throw new Error(`Server responded with ${response.status}: ${response.statusText}. Body: ${text}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Check if the response body is likely JSON or text
|
|
||||||
const contentType = response.headers.get("content-type");
|
|
||||||
if (contentType && contentType.includes("application/json")) {
|
|
||||||
return response.json(); // Parse JSON response
|
|
||||||
} else {
|
|
||||||
return response.text(); // Get response as text
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
console.log(`Upload successful for ${file.name}:`, data);
|
|
||||||
// Add user feedback here
|
|
||||||
statusDiv.textContent = `Successfully uploaded ${file.name}! Server response: ${typeof data === 'object' ? JSON.stringify(data) : data}`;
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error(`Error during upload for ${file.name}:`, error);
|
|
||||||
// Add user feedback here
|
|
||||||
statusDiv.textContent = `Error uploading ${file.name}: ${error.message}`;
|
|
||||||
dropZone.classList.remove('dragover'); // Ensure highlight is removed on error
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue