CoolFace
Apppublic

ArkRega/polyglot

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
server.js127 linesDownload Raw Back to root
1import Fastify from 'fastify'2import cors from '@fastify/cors'3import multipart from '@fastify/multipart'4import helmet from '@fastify/helmet'5import { fetch, FormData, Agent } from 'undici'6 7const app = Fastify({8  logger: {9    transport: {10      target: 'pino-pretty',11      options: {12        colorize: true,13        ignore: 'pid,hostname',14        translateTime: 'HH:MM:ss Z'15      }16    }17  },18  bodyLimit: 157286400  // 150MB limit untuk menangani file besar19})20 21const CONFIG = {22  PORT: process.env.PORT || 7860,23  HOST: '0.0.0.0',24  TARGET: 'https://api.glotfiles.dev/api/generate-polyglot',25  MAX_SIZE: 104857600  // 100MB per file26}27 28const speedAgent = new Agent({29  connections: 100,30  maxIdleTime: 30000,31  pipelining: 1032})33 34app.register(helmet, { contentSecurityPolicy: false })35app.register(cors, { 36  origin: '*',37  exposedHeaders: ['Content-Disposition'] 38})39 40app.register(multipart, {41  limits: {42    fileSize: CONFIG.MAX_SIZE,43    files: 244  }45})46 47app.get('/health', async () => {48  return {49    status: 'online',50    engine: 'CamoFile Turbo v10',51    memory: process.memoryUsage().rss52  }53})54 55app.post('/api/generate', async (request, reply) => {56  const startTime = performance.now()57  app.log.info('Memulai transmisi data cepat CamoFile')58 59  if (!request.isMultipart()) {60    return reply.status(400).send({ error: 'Kirim data dalam format multipart' })61  }62 63  let count = 064  const apiForm = new FormData()65 66  try {67    const parts = request.parts()68    for await (const part of parts) {69      if (part.file) {70        count++71        app.log.info(`Menerima bagian: ${part.fieldname}`)72        // Untuk stabilitas dengan file besar, gunakan stream daripada buffer penuh73        // Namun, FormData memerlukan data lengkap, jadi tetap gunakan buffer dengan batas74        const buffer = await part.toBuffer()75        if (buffer.length > CONFIG.MAX_SIZE) {76          return reply.status(400).send({ error: 'Ukuran file melebihi batas maksimal' })77        }78        const blob = new Blob([buffer], { type: part.mimetype })79        apiForm.append(part.fieldname, blob, part.filename)80      } else {81        apiForm.append(part.fieldname, part.value)82      }83    }84 85    if (count < 2) {86      return reply.status(400).send({ error: 'Lengkapi file gambar dan video' })87    }88 89    const response = await fetch(CONFIG.TARGET, {90      method: 'POST',91      body: apiForm,92      dispatcher: speedAgent93    })94 95    if (!response.ok) {96      const errorText = await response.text()97      app.log.error(`API Error: ${response.status} - ${errorText}`)98      return reply.status(500).send({ error: 'Gagal menghubungi server pusat' })99    }100 101    const duration = (performance.now() - startTime).toFixed(2)102    app.log.info(`Proses selesai dalam ${duration}ms`)103 104    // Gunakan stream untuk response agar lebih efisien memori105    reply.header('Content-Type', 'application/octet-stream')106    reply.header('Content-Disposition', `attachment; filename="CamoFile_Result_${Date.now()}.jpg"`)107    reply.header('X-Camo-Speed', `${duration}ms`)108 109    return reply.send(response.body)  // Kirim stream langsung110 111  } catch (err) {112    app.log.error(err)113    return reply.status(500).send({ error: 'Terjadi gangguan sistem' })114  }115})116 117const start = async () => {118  try {119    await app.listen({ port: CONFIG.PORT, host: CONFIG.HOST })120    console.log(`CamoFile Engine Aktif di Port ${CONFIG.PORT}`)121  } catch (err) {122    app.log.error(err)123    process.exit(1)124  }125}126 127start()