-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
192 lines (170 loc) · 5.16 KB
/
app.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
const express = require("express");
const multer = require("multer");
const axios = require("axios");
const FormData = require("form-data");
const path = require("path");
const cors = require("cors");
// Constants
const IPFS_API = "http://127.0.0.1:5001";
const PORT = 3232;
const MAX_FILE_SIZE = 250 * 1024 * 1024; // 250MB
const HOST = "0.0.0.0";
// Initialize Express app
const app = express();
// Middleware setup
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
app.use(express.static(path.join(__dirname, "public")));
// Configure multer for file uploads
const storage = multer.memoryStorage();
const upload = multer({
storage,
limits: { fileSize: MAX_FILE_SIZE },
fileFilter: (req, file, cb) => {
// Add file type validation if needed
cb(null, true);
},
});
// Error handling middleware
const errorHandler = (err, req, res, next) => {
console.error("Unexpected error:", err.stack);
res.status(500).json({ error: "Internal server error" });
};
// Upload endpoint
app.post("/upload", upload.single("file"), async (req, res) => {
try {
// Validate file presence
if (!req.file) {
return res.status(400).json({
error: "No file uploaded",
status: "failed",
timestamp: new Date().toISOString(),
});
}
// Prepare file for IPFS
const formData = new FormData();
formData.append("file", req.file.buffer, {
filename: req.file.originalname,
contentType: req.file.mimetype,
knownLength: req.file.size,
});
// Upload to IPFS
const uploadStart = Date.now();
const response = await axios.post(`${IPFS_API}/api/v0/add`, formData, {
headers: { ...formData.getHeaders() },
timeout: 30000, // 30s timeout
});
// Detailed logging
const uploadDetails = {
name: req.file.originalname,
size_bytes: req.file.size,
mime_type: req.file.mimetype,
cid: response.data.Hash,
upload_duration_ms: Date.now() - uploadStart,
timestamp: new Date().toISOString(),
};
console.log("File uploaded successfully:", uploadDetails);
// Response with more details
res.json({
status: "success",
cid: response.data.Hash,
filename: req.file.originalname,
size: req.file.size,
details: uploadDetails,
});
} catch (err) {
if (err instanceof multer.MulterError) {
if (err.code === "LIMIT_FILE_SIZE") {
return res.status(400).json({
error: `File too large. Max size is ${
MAX_FILE_SIZE / (1024 * 1024)
}MB`,
status: "failed",
timestamp: new Date().toISOString(),
});
}
return res.status(400).json({ error: err.message, status: "failed" });
}
console.error("IPFS upload error:", {
message: err.message,
stack: err.stack,
timestamp: new Date().toISOString(),
});
res.status(500).json({
error: "Failed to upload to IPFS",
details: err.message,
status: "failed",
timestamp: new Date().toISOString(),
});
}
});
// Enhanced status endpoint
app.get("/status", async (req, res) => {
try {
// Fetch multiple IPFS stats concurrently
const [bwResponse, repoResponse, idResponse] = await Promise.all([
axios.post(`${IPFS_API}/api/v0/stats/bw?interval=5m`, { timeout: 5000 }),
axios.post(`${IPFS_API}/api/v0/repo/stat`, { timeout: 5000 }),
axios.post(`${IPFS_API}/api/v0/id`, { timeout: 5000 }),
]);
// Format bandwidth data
const bandwidth = {
totalIn: bwResponse.data.TotalIn,
totalOut: bwResponse.data.TotalOut,
rateIn: bwResponse.data.RateIn,
rateOut: bwResponse.data.RateOut,
interval: "1h",
};
// Format repository stats
const repo = {
size: repoResponse.data.RepoSize,
storageMax: repoResponse.data.StorageMax,
numObjects: repoResponse.data.NumObjects,
path: repoResponse.data.RepoPath,
version: repoResponse.data.Version,
};
// Node identity info
const nodeInfo = {
id: idResponse.data.ID,
publicKey: idResponse.data.PublicKey,
addresses: idResponse.data.Addresses,
agentVersion: idResponse.data.AgentVersion,
protocolVersion: idResponse.data.ProtocolVersion,
};
const peersResponse = await axios.post(`${IPFS_API}/api/v0/swarm/peers`, {
timeout: 5000,
});
const connectedPeers = {
count: peersResponse.data.Peers.length,
list: peersResponse.data.Peers,
};
res.json({
status: "success",
timestamp: new Date().toISOString(),
bandwidth,
repository: repo,
node: nodeInfo,
peers: connectedPeers,
});
} catch (err) {
console.error("Status check error:", {
message: err.message,
stack: err.stack,
timestamp: new Date().toISOString(),
});
res.status(503).json({
error: "Failed to retrieve IPFS status",
details: err.message,
status: "failed",
timestamp: new Date().toISOString(),
});
}
});
// Apply error handler
app.use(errorHandler);
// Start server
app.listen(PORT, HOST, () => {
console.log(`Server running on http://${HOST}:${PORT}`);
console.log(`IPFS API endpoint: ${IPFS_API}`);
});