Skip to content

Instantly share code, notes, and snippets.

@Dialga
Created January 12, 2015 15:02
Show Gist options
  • Save Dialga/1e19779ac7d0c77df579 to your computer and use it in GitHub Desktop.
Save Dialga/1e19779ac7d0c77df579 to your computer and use it in GitHub Desktop.
Basic civetweb + PH7 web server
/*
* Extremely minimal civetweb(formerly mongoose) + PH7 scripted web server for embedded use,
* or just a lightweight alternative to your usual PHP and Apache, nginx, lighttpd.
* Serves up files and PH7 scripts from the directory run.
* Compiles on linux with:
* cc -Wall -pipe -DPH7_ENABLE_MATH_FUNC -O2 -lm -ldl -lpthread civetweb.c ph7.c ph7_server.c -o server
* Windows: untested
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "civetweb.h"
#include "ph7.h"
static struct mg_context *ctx; /* Set by start_civetweb() */
static ph7 *pEngine; /* PH7 engine */
static ph7_vm *pVm; /* Compiled PHP program */
int exit_flag = 0;
// Display an error message and exit.
static void Fatal(const char *zMsg){
puts(zMsg);
ph7_lib_shutdown();
mg_stop(ctx);
exit(0);
}
#define STDOUT_FILENO 1
/*
* VM output consumer callback.
* Each time the virtual machine generates some outputs,the following
* function gets called by the underlying virtual machine to consume
* the generated output.
* All this function does is redirecting the VM output to STDOUT.
* This function is registered later via a call to ph7_vm_config()
* with a configuration verb set to: PH7_VM_CONFIG_OUTPUT.
*/
static int Output_Consumer(
const void *pOutput,
unsigned int nOutputLen,
void *pUserData // Unused
){
ssize_t nWr;
nWr = printf("%.*s", nOutputLen, pOutput);
if( nWr < 0 ){
return PH7_ABORT;
}
return PH7_OK;
}
int ph7_script(struct mg_connection *conn, void *cbdata){
int rc;
const void *pOut;
unsigned int nLen;
/* Handler may access the request info using mg_get_request_info */
struct mg_request_info * req_info = mg_get_request_info(conn);
/* Now,it's time to compile our PHP file */
rc = ph7_compile_file(
pEngine, /* PH7 Engine */
req_info->uri+1, /* Path to the PHP file to compile */
&pVm, /* OUT: Compiled PHP program */
0 /* IN: Compile flags */
);
if( rc != PH7_OK ){ /* Compile error */
if( rc == PH7_IO_ERR ){
Fatal("IO error while opening the target file");
}else if( rc == PH7_VM_ERR ){
Fatal("VM initialization error");
}else{
/* Compile-time error, your output (STDOUT) should display the error messages */
Fatal("Compile error");
}
}
rc = ph7_vm_exec(pVm,0);
if( rc != PH7_OK ){
Fatal("VM execution error");
}
/*
* Now we have our script compiled,it's time to configure our VM.
* We will install the VM output consumer callback defined above
* so that we can consume the VM output and redirect it to STDOUT.
*/
/* Extract the output */
rc = ph7_vm_config(pVm,
PH7_VM_CONFIG_EXTRACT_OUTPUT,
&pOut,
&nLen
);
if(nLen > 0){
mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n");
mg_write(conn, pOut, nLen);
}
#if REPORT_ERRORS+1
/* Report script run-time errors */
ph7_vm_config(pVm,PH7_VM_CONFIG_ERR_REPORT);
#endif
ph7_vm_reset(pVm);
return 1;
}
int main(int argc, char **argv){
int rc;
const char * options[] = {
"document_root", ".",
"listening_ports", "8080",
0
};
/* Allocate a new PH7 engine instance */
rc = ph7_init(&pEngine);
if( rc != PH7_OK ){
Fatal("Error while allocating a new PH7 engine instance");
}
/* Set an error log consumer callback. This callback [Output_Consumer()] will
* redirect all compile-time error messages to STDOUT.
*/
ph7_config(pEngine,PH7_CONFIG_ERR_OUTPUT,
Output_Consumer, // Error log consumer
0 // NULL: Callback Private data
);
// Start the web server.
ctx = mg_start(NULL, NULL, options);
mg_set_request_handler(ctx, "**.php$", ph7_script, 0);
printf("%s started on port(s) %s with web root [%s]\n",
argv[0], mg_get_option(ctx, "listening_ports"),
mg_get_option(ctx, "document_root"));
while (exit_flag == 0) {
#ifdef _WIN32
Sleep(1000);
#else
sleep(1);
#endif
}
ph7_vm_release(pVm);
ph7_release(pEngine);
mg_stop(ctx);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment