I’ve developed a chat application based on the OpenAI API. Locally, I’ve written my application in such a way that the data is sent in streaming, bit by bit; this allows you to see the message being written bit by bit. My proxy.php file takes care of this on the backend, processed by React on the front :
<?php
ob_implicit_flush(true);
// Log all request details
file_put_contents('debug.log', print_r($_SERVER, true) . "nn" . file_get_contents('php://input') . "nn", FILE_APPEND);
// Liste des origines autorisées
$allowed_origins = array(
'https://philogpt.vmirebeau.fr',
'http://localhost:3000',
'http://localhost'
);
// Détecter l'origine de la requête
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (in_array($origin, $allowed_origins)) {
header("Access-Control-Allow-Origin: " . $origin);
} else {
// Par défaut, interdire l'accès si l'origine n'est pas autorisée
header("Access-Control-Allow-Origin: null");
}
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
exit(0);
}
// Récupérer les données JSON
$json_data = file_get_contents('php://input');
$data = json_decode($json_data, true);
// Vérifier si la clé 'input' existe dans les données JSON
if (!isset($data['input'])) {
http_response_code(400); // Bad Request
echo "Champ 'input' manquant dans les données JSON.";
exit;
}
// Récupérer et assigner la valeur de 'input'
$input = $data['input'];
header('Content-Type: application/json');
// Lire la clé API à partir de la variable d'environnement
$api_key = MY_API_KEY;
if (!$api_key) {
http_response_code(500); // Internal Server Error
echo "Clé API non trouvée.";
exit;
}
// Préparer les données de la requête à envoyer à l'API GPT
$data = array(
'model' => 'gpt-4o-mini',
'stream' => true,
'messages' => $input // Transmettre directement l'historique des messages reçu dans 'input'
);
// Définir les options curl pour la requête API
$options = array(
CURLOPT_URL => 'https://api.openai.com/v1/chat/completions',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Authorization: Bearer ' . $api_key
),
// Traiter chaque fragment de données au fur et à mesure qu'il arrive
CURLOPT_WRITEFUNCTION => function($ch, $chunk) {
echo $chunk;
return strlen($chunk);
}
);
// Initialiser la requête curl
$ch = curl_init();
// Définir les options curl spécifiées précédemment
curl_setopt_array($ch, $options);
// Exécuter la requête curl et fermer la connexion
curl_exec($ch);
curl_close($ch);
?>
Unfortunately, when I deploy it on my ovh.com hosting (I have a basic “personal hosting” package, if that’s relevant), the data streaming doesn’t work: I only see the complete message arrive, once it’s completely finished. This is a pity for the user experience, as it lengthens waiting times.
I tried unsuccessfully to configure my .htaccess:
<IfModule mod_proxy_http.c>
SetEnv proxy-sendchunked 1
# Disable buffering for this route
SetEnvIf Request_URI “^/server/proxy.php” proxy-sendchunked
</IfModule>
# Disable compression to avoid interfering with streaming
<IfModule mod_deflate.c>
SetEnv no-gzip 1
</IfModule>
# Enable CORS requests if necessary
<IfModule mod_headers.c>
Header always set Access-Control-Allow-Origin “*”
Header always set Access-Control-Allow-Methods “POST, GET, OPTIONS”
Header always set Access-Control-Allow-Headers “Content-Type”
</IfModule>
# Avoid caching for proxy responses
<IfModule mod_headers.c>
Header set Cache-Control “no-store, no-cache, must-revalidate, max-age=0”
</IfModule>
Do you have a solution?
Thank you,
Vivien
2