Commit a6bcb9fd authored by conrad's avatar conrad

add basic cgi capability to oggz-chop. Currently uses start and end

URL parameters, will switch to proper time URIs in a future revision.
This patch adds an example apache config to use oggz-chop as a handler for
application/ogg, and a script for installing it on Debian based systems.


git-svn-id: http://svn.annodex.net/liboggz/trunk@3503 8158c8cd-e7e1-0310-9fa4-c5954c97daef
parent 4208d217
<IfModule mod_actions.c>
ScriptAlias /oggz-chop /usr/local/bin/oggz-chop
Action application/ogg /oggz-chop
</IfModule>
#!/bin/sh
PATH="/bin:/usr/bin:/sbin:/usr/sbin"
if dpkg -l apache2 >/dev/null 2>&1; then
DAEMON="apache2"
cp apache/oggz-chop.conf /etc/apache2/conf.d/
elif dpkg -l apache >/dev/null 2>&1; then
DAEMON="apache"
cp apache/oggz-chop.conf /etc/apache/conf.d
else
echo 1>&2 "Error: Neither apache2 or apache are installed"
exit 1
fi
invoke-rc.d $DAEMON reload || true
......@@ -22,7 +22,7 @@ TESTS = httpdate_test
noinst_HEADERS = alloc_snprintf.h cgi.h cmd.h header.h httpdate.h memory.h oggz-chop.h tests.h
oggz_chop_SOURCES = oggz-chop.c ../oggz_tools.c cmd.c main.c
oggz_chop_SOURCES = oggz-chop.c ../oggz_tools.c cmd.c cgi.c header.c httpdate.c main.c
oggz_chop_LDADD = $(OGGZ_LIBS)
httpdate_test_SOURCES = httpdate.c httpdate_test.c
......
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "oggz-chop.h"
#include "header.h"
#include "httpdate.h"
static void
set_param (OCState * state, char * key, char * val)
{
if (!strncmp ("s", key, 2)) state->start = atof(val);
if (!strncmp ("start", key, 6)) state->start = atof(val);
if (!strncmp ("e", key, 2)) state->end = atof(val);
if (!strncmp ("end", key, 6)) state->end = atof(val);
}
/**
* Parse the name=value pairs in the query string and set parameters
* @param start,end The range parameters to set
* @param query The query string
*/
static void
parse_query (OCState * state, char * query)
{
char * key, * val, * end;
if (!query) return;
key = query;
do {
val = strchr (key, '=');
end = strchr (key, '&');
if (end) {
if (val) {
if (val < end) {
*val++ = '\0';
} else {
val = NULL;
}
}
*end++ = '\0';
} else {
if (val) *val++ = '\0';
}
/* fprintf (stderr, "%s = %s\n", key, val);*/
set_param (state, key, val);
key = end;
} while (end != NULL);
return;
}
int
cgi_test (void)
{
char * gateway_interface;
gateway_interface = getenv ("GATEWAY_INTERFACE");
if (gateway_interface == NULL) {
return 0;
}
return 1;
}
#if 0
static int
cgi_send_photo (photo_t * photo)
{
/*header_content_length (photo->size);*/
header_end();
photo_put (photo);
return 0;
}
static int
cgi_send (OCState * state)
{
header_last_modified (state->in.mtime);
if (params->nochange) {
cgi_send_photo (&params->in);
} else if (params->out.name) {
cgi_send_photo (&params->out);
} else {
header_content_length ((off_t)params->data_size);
header_end();
memory_send (params);
}
return 0;
}
#endif
int
cgi_main (OCState * state)
{
int err = 0;
char * path_info;
char * path_translated;
char * query_string;
char * if_modified_since;
time_t since_time;
httpdate_init ();
path_info = getenv ("PATH_INFO");
path_translated = getenv ("PATH_TRANSLATED");
query_string = getenv ("QUERY_STRING");
if_modified_since = getenv ("HTTP_IF_MODIFIED_SINCE");
state->infilename = path_translated;
state->outfilename = NULL;
state->start = 0.0;
state->end = -1.0;
/*photo_init (&params->in, path_translated);*/
#if 0
if (if_modified_since != NULL) {
int len;
fprintf (stderr, "If-Modified-Since: %s\n", if_modified_since);
len = strlen (if_modified_since) + 1;
since_time = httpdate_parse (if_modified_since, len);
if (state->in.mtime <= since_time) {
header_not_modified();
header_end();
return 1;
}
}
#endif
header_content_type_ogg ();
/*config_init (params);*/
parse_query (state, query_string);
#if 0
if (params->x || params->y || params->scale || params->gray ||
params->quality) {
cache_init (params, path_info);
} else {
params->nochange = 1;
}
#endif
header_end();
err = 0;
#if 0
if (!(params->nochange || params->cached)) {
err = chop (state);
}
#else
err = chop (state);
#endif
return err;
}
#ifndef __CGI_H__
#define __CGI_H__
#include "oggz-chop.h"
int cgi_test (void);
int cgi_main (OCState * state);
#endif /* __CGI_H__ */
......@@ -30,12 +30,10 @@ usage (char * progname)
}
int
cmd_main (int argc, char * argv[])
cmd_main (OCState * state, int argc, char * argv[])
{
int show_version = 0;
int show_help = 0;
double start = 0.0, end = -1.0;
char * infilename = NULL, * outfilename = NULL;
int i;
progname = argv[0];
......@@ -45,6 +43,11 @@ cmd_main (int argc, char * argv[])
return (1);
}
state->start = 0.0;
state->end = -1.0;
state->infilename = NULL;
state->outfilename = NULL;
while (1) {
char * optstring = "s:e:o:hv";
......@@ -70,10 +73,10 @@ cmd_main (int argc, char * argv[])
switch (i) {
case 's': /* start */
start = atof (optarg);
state->start = atof (optarg);
break;
case 'e': /* end */
end = atof (optarg);
state->end = atof (optarg);
break;
case 'h': /* help */
show_help = 1;
......@@ -82,7 +85,7 @@ cmd_main (int argc, char * argv[])
show_version = 1;
break;
case 'o': /* output */
outfilename = optarg;
state->outfilename = optarg;
break;
default:
break;
......@@ -106,9 +109,9 @@ cmd_main (int argc, char * argv[])
goto exit_err;
}
infilename = argv[optind++];
state->infilename = argv[optind++];
return chop (infilename, outfilename, start, end);
return chop (state);
exit_ok:
return 0;
......
#ifndef __CMD_H__
#define __CMD_H__
int cmd_main (int argc, char * argv[]);
int cmd_main (OCState * state, int argc, char * argv[]);
#endif /* __CMD_H__ */
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "httpdate.h"
#define CONTENT_TYPE_OGG "Content-Type: application/ogg\n"
int
header_last_modified (time_t mtime)
{
char buf[30];
httpdate_snprint (buf, 30, mtime);
return printf ("Last-Modified: %s\n", buf);
}
int
header_not_modified (void)
{
fprintf (stderr, "304 Not Modified\n");
return printf ("Status: 304 Not Modified\n");
}
int
header_content_type_ogg ()
{
return printf (CONTENT_TYPE_OGG);
}
int
header_content_length (off_t len)
{
return printf ("Content-Length: %ld\n", (long)len);
}
int
header_end (void)
{
putchar('\n');
fflush (stdout);
return 0;
}
#ifndef __HEADER_H__
#define __HEADER_H__
int header_content_type_ogg (void);
int header_content_length (int len);
int header_last_modified (time_t mtime);
int header_not_modified (void);
int header_end (void);
#endif /* __HEADER_H__ */
#ifndef __HTTPDATE_H__
#define __HTTPDATE_H__
#include <time.h>
void httpdate_init (void);
int httpdate_snprint (char * buf, int n, time_t mtime);
time_t httpdate_parse (char * s, int n);
#endif /* __HTTPDATE_H__ */
......@@ -5,23 +5,20 @@
#include <string.h>
#include "oggz-chop.h"
/*#include "cgi.h"*/
#include "cgi.h"
#include "cmd.h"
int
main (int argc, char * argv[])
{
OCState state;
int err = 0;
#if 0
if (cgi_test ()) {
err = cgi_main (&params);
err = cgi_main (&state);
} else {
err = cmd_main (&params, argc, argv);
err = cmd_main (&state, argc, argv);
}
#else
err = cmd_main (argc, argv);
#endif
if (err) return 1;
else return 0;
......
......@@ -278,35 +278,31 @@ read_bos (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
}
int
chop (char * infilename, char * outfilename, double start, double end)
chop (OCState * state)
{
OCState state;
OGGZ * oggz;
state.tracks = oggz_table_new ();
state->tracks = oggz_table_new ();
if (strcmp (infilename, "-") == 0) {
if (strcmp (state->infilename, "-") == 0) {
oggz = oggz_open_stdio (stdin, OGGZ_READ|OGGZ_AUTO);
} else {
oggz = oggz_open (infilename, OGGZ_READ|OGGZ_AUTO);
oggz = oggz_open (state->infilename, OGGZ_READ|OGGZ_AUTO);
}
if (outfilename == NULL) {
state.outfile = stdout;
if (state->outfilename == NULL) {
state->outfile = stdout;
} else {
state.outfile = fopen (outfilename, "wb");
if (state.outfile == NULL) {
state->outfile = fopen (state->outfilename, "wb");
if (state->outfile == NULL) {
fprintf (stderr, "oggz-chop: unable to open output file %s\n",
outfilename);
state->outfilename);
return -1;
}
}
state.start = start;
state.end = end;
/* set up a demux filter */
oggz_set_read_page (oggz, -1, read_bos, &state);
oggz_set_read_page (oggz, -1, read_bos, state);
oggz_run_set_blocksize (oggz, 1024*1024);
oggz_run (oggz);
......
......@@ -39,8 +39,12 @@
*/
typedef struct _OCState {
char * infilename;
char * outfilename;
OggzTable * tracks;
FILE * outfile;
double start;
double end;
} OCState;
......@@ -61,6 +65,6 @@ typedef struct _OCTrackState {
} OCTrackState;
int chop (char * infilename, char * outfilename, double start, double end);
int chop (OCState * state);
#endif /* __OGGZ_CHOP_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment