srivatsavdamaraju commited on
Commit
1ce6e16
Β·
verified Β·
1 Parent(s): 8d90300

Create server.js

Browse files
Files changed (1) hide show
  1. server.js +192 -0
server.js ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const express = require("express");
2
+ const cors = require("cors");
3
+ const puppeteer = require("puppeteer");
4
+
5
+ const app = express();
6
+ const PORT = process.env.PORT || 7860;
7
+
8
+ // Middleware
9
+ app.use(cors());
10
+ app.use(express.json({ limit: "10mb" }));
11
+
12
+ // Root endpoint - Health check
13
+ app.get("/", (_req, res) => {
14
+ res.json({
15
+ status: "ok",
16
+ message: "HTML to PDF API is running",
17
+ version: "1.0.0",
18
+ endpoints: {
19
+ health: "GET / or GET /health",
20
+ convert: "POST /api/html-to-pdf"
21
+ },
22
+ usage: {
23
+ method: "POST",
24
+ url: "/api/html-to-pdf",
25
+ body: {
26
+ html_content: "Your HTML content here",
27
+ pdf_options: {
28
+ format: "A4",
29
+ printBackground: true,
30
+ margin: {
31
+ top: "10mm",
32
+ right: "10mm",
33
+ bottom: "10mm",
34
+ left: "10mm"
35
+ }
36
+ }
37
+ }
38
+ }
39
+ });
40
+ });
41
+
42
+ // Health check endpoint
43
+ app.get("/health", (_req, res) => {
44
+ res.json({
45
+ status: "healthy",
46
+ timestamp: new Date().toISOString(),
47
+ uptime: process.uptime()
48
+ });
49
+ });
50
+
51
+ // Main PDF conversion endpoint
52
+ app.post("/api/html-to-pdf", async (req, res) => {
53
+ let browser;
54
+ const startTime = Date.now();
55
+
56
+ try {
57
+ const { html_content: htmlContent, pdf_options: pdfOptions } = req.body || {};
58
+
59
+ // Validate input
60
+ if (!htmlContent || !htmlContent.trim()) {
61
+ return res.status(400).json({
62
+ error: "html_content is required",
63
+ success: false
64
+ });
65
+ }
66
+
67
+ console.log(`[${new Date().toISOString()}] Starting PDF generation...`);
68
+
69
+ // Launch browser with Puppeteer's bundled Chromium
70
+ browser = await puppeteer.launch({
71
+ args: [
72
+ "--no-sandbox",
73
+ "--disable-setuid-sandbox",
74
+ "--disable-dev-shm-usage",
75
+ "--disable-gpu",
76
+ "--disable-software-rasterizer",
77
+ "--disable-extensions",
78
+ "--disable-background-networking",
79
+ "--disable-default-apps",
80
+ "--disable-sync",
81
+ "--metrics-recording-only",
82
+ "--mute-audio",
83
+ "--no-first-run",
84
+ "--single-process",
85
+ "--disable-accelerated-2d-canvas"
86
+ ],
87
+ headless: "new"
88
+ });
89
+
90
+ const page = await browser.newPage();
91
+
92
+ // Set content
93
+ await page.setContent(
94
+ `<!DOCTYPE html>
95
+ <html>
96
+ <head>
97
+ <meta charset="utf-8" />
98
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
99
+ </head>
100
+ <body>
101
+ ${htmlContent}
102
+ </body>
103
+ </html>`,
104
+ {
105
+ waitUntil: "networkidle0",
106
+ timeout: 30000
107
+ }
108
+ );
109
+
110
+ // Generate PDF with default options merged with user options
111
+ const defaultPdfOptions = {
112
+ format: "A4",
113
+ printBackground: true,
114
+ margin: {
115
+ top: "10mm",
116
+ right: "10mm",
117
+ bottom: "10mm",
118
+ left: "10mm"
119
+ }
120
+ };
121
+
122
+ const pdfBuffer = await page.pdf({
123
+ ...defaultPdfOptions,
124
+ ...(pdfOptions || {})
125
+ });
126
+
127
+ await browser.close();
128
+ browser = null;
129
+
130
+ const processingTime = Date.now() - startTime;
131
+ console.log(`[${new Date().toISOString()}] PDF generated successfully in ${processingTime}ms`);
132
+
133
+ res.json({
134
+ pdf_base64: pdfBuffer.toString("base64"),
135
+ success: true,
136
+ processing_time_ms: processingTime,
137
+ pdf_size_bytes: pdfBuffer.length
138
+ });
139
+
140
+ } catch (err) {
141
+ console.error(`[${new Date().toISOString()}] PDF Generation Error:`, err);
142
+
143
+ if (browser) {
144
+ try {
145
+ await browser.close();
146
+ } catch (closeErr) {
147
+ console.error("Browser close error:", closeErr);
148
+ }
149
+ }
150
+
151
+ res.status(500).json({
152
+ error: "Failed to generate PDF",
153
+ details: err.message,
154
+ success: false
155
+ });
156
+ }
157
+ });
158
+
159
+ // 404 handler
160
+ app.use((_req, res) => {
161
+ res.status(404).json({
162
+ error: "Endpoint not found",
163
+ available_endpoints: [
164
+ "GET /",
165
+ "GET /health",
166
+ "POST /api/html-to-pdf"
167
+ ]
168
+ });
169
+ });
170
+
171
+ // Start server
172
+ app.listen(PORT, "0.0.0.0", () => {
173
+ console.log(`
174
+ ╔════════════════════════════════════════╗
175
+ β•‘ HTML to PDF API Server β•‘
176
+ β•‘ Status: Running βœ… β•‘
177
+ β•‘ Port: ${PORT} β•‘
178
+ β•‘ URL: http://0.0.0.0:${PORT} β•‘
179
+ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
180
+ `);
181
+ });
182
+
183
+ // Graceful shutdown
184
+ process.on('SIGTERM', () => {
185
+ console.log('SIGTERM signal received: closing HTTP server');
186
+ process.exit(0);
187
+ });
188
+
189
+ process.on('SIGINT', () => {
190
+ console.log('SIGINT signal received: closing HTTP server');
191
+ process.exit(0);
192
+ });