-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.js
143 lines (115 loc) · 3.55 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
let http = require('http');
let static = require('node-static');
let fileServer = new static.Server('.');
let path = require('path');
let fs = require('fs');
//let console.log = require('console.log')('example:resume-upload');
let uploads = Object.create(null);
let dir = "./";
function onUpload(req, res) {
let fileId = req.headers['x-file-id'];
let startByte = +req.headers['x-start-byte'];
if (!fileId) {
res.writeHead(400, "No file id");
res.end();
}
// we'll files "nowhere"
//let filePath = '/dev/null';
// could use a real path instead, e.g.
let filePath = path.join(dir, fileId);
console.log("onUpload fileId: "+ fileId);
// initialize a new upload
if (!uploads[fileId]) uploads[fileId] = {};
let upload = uploads[fileId];
console.log("bytesReceived:" + upload.bytesReceived + " startByte:" + startByte)
let fileStream;
// if startByte is 0 or not set, create a new file, otherwise check the size and append to existing one
if (!startByte) {
upload.bytesReceived = 0;
fileStream = fs.createWriteStream(filePath, {
flags: 'w'
});
console.log("New file created: " + filePath);
} else {
// we can check on-disk file size as well to be sure
if (upload.bytesReceived != startByte) {
res.writeHead(400, "Wrong start byte");
res.end(upload.bytesReceived);
return;
}
// append to existing file
fileStream = fs.createWriteStream(filePath, {
flags: 'a'
});
console.log("File reopened: " + filePath);
}
req.on('data', function(data) {
console.log("bytes received "+ upload.bytesReceived);
upload.bytesReceived += data.length;
});
// send request body to file
req.pipe(fileStream);
// when the request is finished, and all its data is written
fileStream.on('close', function() {
if (upload.bytesReceived == req.headers['x-file-size']) {
console.log("Upload finished");
delete uploads[fileId];
// can do something else with the uploaded file here
// uploads = Object.create(null);
res.end("Success " + upload.bytesReceived);
} else {
// connection lost, we leave the unfinished file around
console.log("File unfinished, stopped at " + upload.bytesReceived);
res.end();
}
});
// in case of I/O error - finish the request
fileStream.on('error', function(err) {
console.log("fileStream error");
res.writeHead(500, "File error");
res.end();
});
}
function onStatus(req, res) {
let fileId = req.headers['x-file-id'];
let upload = uploads[fileId];
console.log("onStatus fileId: " + fileId + " upload:" + upload);
if (typeof upload == 'undefined') {
res.end("0")
} else {
// res.end("0")
res.end(String(upload.bytesReceived));
}
}
function accept(req, res) {
if(req.headers['x-quit'] == "1" ) {
console.log("quitting")
fs.access(req.headers['x-file-id'], fs.F_OK, (err) => {
if (err) {
console.error(err)
return
}
//file exists
fs.unlink(req.headers['x-file-id'], function (err) {
if (err) throw err;
// if no error, file has been deleted successfully
console.log('File deleted!');
res.end();
});
})
}
if (req.url == '/status') {
onStatus(req, res);
} else if (req.url == '/upload' && req.method == 'POST') {
onUpload(req, res);
} else {
fileServer.serve(req, res);
}
}
// -----------------------------------
if (!module.parent) {
http.createServer(accept).listen(8080);
console.log('Server listening at port 8080');
} else {
exports.accept = accept;
}