Skip to content
Browse files

first

  • Loading branch information...
1 parent 4cc1815 commit c14e729a1d9c776e2673cbf38e96377e7dabb1d0 @xcir committed Jun 3, 2012
View
30 .gitignore
@@ -0,0 +1,30 @@
+Makefile
+Makefile.in
+.deps/
+.libs/
+*.o
+*.lo
+*.la
+*~
+vmod_postparse.3
+
+/aclocal.m4
+/autom4te.cache/
+/compile
+/config.guess
+/config.h
+/config.h.in
+/config.log
+/config.status
+/config.sub
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/missing
+/stamp-h1
+/m4/*.m4
+
+/src/vcc_if.c
+/src/vcc_if.h
View
5 COPYING
@@ -0,0 +1,5 @@
+libvmod-postparse, easy rewrite for Varnish:
+Copyright (c) 2012 Syohei Tanaka(@xcir)
+
+File layout and configuration based on libvmod-example:
+Copyright (c) 2011 Varnish Software AS
View
20 LICENSE
@@ -0,0 +1,20 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
View
18 Makefile.am
@@ -0,0 +1,18 @@
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = src
+
+EXTRA_DIST = README.rst
+
+dist_man_MANS = vmod_postparse.3
+MAINTAINERCLEANFILES = $(dist_man_MANS)
+
+vmod_postparse.3: README.rst
+if HAVE_RST2MAN
+ ${RST2MAN} README.rst $@
+else
+ @echo "========================================"
+ @echo "You need rst2man installed to make dist"
+ @echo "========================================"
+ @false
+endif
View
94 README.rst
@@ -0,0 +1,94 @@
+===================
+vmod_postparse
+===================
+
+-------------------------------
+Varnish parse post data module
+-------------------------------
+
+:Author: Syohei Tanaka(@xcir)
+:Date: 2012-06-03
+:Version: 0.1
+:Manual section: 3
+
+SYNOPSIS
+===========
+
+import postparse;
+
+DESCRIPTION
+==============
+
+
+FUNCTIONS
+============
+
+parse
+-------------
+
+Prototype
+ ::
+
+ parse(STRING targethead,BOOL parsefile)
+Return value
+ INT
+Description
+ get POST request(Only "application/x-www-form-urlencoded" "multipart/mixed")
+Example
+ ::
+
+ if(postparse.parse("x-test",false) == 1){
+ std.log("raw: " + req.http.x-test);
+ std.log("submitter: " + req.http.submitter);
+ }
+
+ //response
+ 12 VCL_Log c raw: submitter=abcdef&submitter2=b
+ 12 VCL_Log c submitter: abcdef
+
+
+INSTALLATION
+==================
+
+Installation requires Varnish source tree.
+
+Usage::
+
+ ./autogen.sh
+ ./configure VARNISHSRC=DIR [VMODDIR=DIR]
+
+`VARNISHSRC` is the directory of the Varnish source tree for which to
+compile your vmod. Both the `VARNISHSRC` and `VARNISHSRC/include`
+will be added to the include search paths for your module.
+
+Optionally you can also set the vmod install directory by adding
+`VMODDIR=DIR` (defaults to the pkg-config discovered directory from your
+Varnish installation).
+
+Make targets:
+
+* make - builds the vmod
+* make install - installs your vmod in `VMODDIR`
+* make check - runs the unit tests in ``src/tests/*.vtc``
+
+
+HISTORY
+===========
+
+Version 0.1: add function parse
+
+COPYRIGHT
+=============
+
+This document is licensed under the same license as the
+libvmod-rewrite project. See LICENSE for details.
+
+* Copyright (c) 2012 Syohei Tanaka(@xcir)
+
+File layout and configuration based on libvmod-example
+
+* Copyright (c) 2011 Varnish Software AS
+
+parse method based on VFW( https://github.com/scarpellini/VFW )
+
+url encode method based on http://d.hatena.ne.jp/hibinotatsuya/20091128/1259404695
View
44 autogen.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+warn() {
+ echo "WARNING: $@" 1>&2
+}
+
+case `uname -s` in
+Darwin)
+ LIBTOOLIZE=glibtoolize
+ ;;
+FreeBSD)
+ LIBTOOLIZE=libtoolize
+ ;;
+Linux)
+ LIBTOOLIZE=libtoolize
+ ;;
+SunOS)
+ LIBTOOLIZE=libtoolize
+ ;;
+*)
+ warn "unrecognized platform:" `uname -s`
+ LIBTOOLIZE=libtoolize
+esac
+
+automake_version=`automake --version | tr ' ' '\n' | egrep '^[0-9]\.[0-9a-z.-]+'`
+if [ -z "$automake_version" ] ; then
+ warn "unable to determine automake version"
+else
+ case $automake_version in
+ 0.*|1.[0-8]|1.[0-8][.-]*)
+ warn "automake ($automake_version) detected; 1.9 or newer recommended"
+ ;;
+ *)
+ ;;
+ esac
+fi
+
+set -ex
+
+aclocal -I m4
+$LIBTOOLIZE --copy --force
+autoheader
+automake --add-missing --copy --foreign
+autoconf
View
72 configure.ac
@@ -0,0 +1,72 @@
+AC_PREREQ(2.59)
+AC_COPYRIGHT([Copyright (c) 2012 Syohei Tanaka(@xcir)])
+AC_INIT([libvmod-postparse], [trunk])
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_SRCDIR(src/vmod_postparse.vcc)
+AM_CONFIG_HEADER(config.h)
+
+AC_CANONICAL_SYSTEM
+AC_LANG(C)
+
+AM_INIT_AUTOMAKE([foreign])
+
+AC_GNU_SOURCE
+AC_PROG_CC
+AC_PROG_CC_STDC
+if test "x$ac_cv_prog_cc_c99" = xno; then
+ AC_MSG_ERROR([Could not find a C99 compatible compiler])
+fi
+AC_PROG_CPP
+
+AC_PROG_INSTALL
+AC_PROG_LIBTOOL
+AC_PROG_MAKE_SET
+
+# Check for rst utilities
+AC_CHECK_PROGS(RST2MAN, [rst2man rst2man.py], "no")
+if test "x$RST2MAN" = "xno"; then
+ AC_MSG_WARN([rst2man not found - not building man pages])
+fi
+AM_CONDITIONAL(HAVE_RST2MAN, [test "x$RST2MAN" != "xno"])
+
+# Check for pkg-config
+PKG_PROG_PKG_CONFIG
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([sys/stdlib.h])
+
+# Check for python
+AC_CHECK_PROGS(PYTHON, [python3 python3.1 python3.2 python2.7 python2.6 python2.5 python2 python], [AC_MSG_ERROR([Python is needed to build this vmod, please install python.])])
+
+# Varnish source tree
+AC_ARG_VAR([VARNISHSRC], [path to Varnish source tree (mandatory)])
+if test "x$VARNISHSRC" = x; then
+ AC_MSG_ERROR([No Varnish source tree specified])
+fi
+VARNISHSRC=`cd $VARNISHSRC && pwd`
+AC_CHECK_FILE([$VARNISHSRC/include/varnishapi.h],
+ [],
+ [AC_MSG_FAILURE(["$VARNISHSRC" is not a Varnish source directory])]
+)
+
+# Check that varnishtest is built in the varnish source directory
+AC_CHECK_FILE([$VARNISHSRC/bin/varnishtest/varnishtest],
+ [],
+ [AC_MSG_FAILURE([Can't find "$VARNISHSRC/bin/varnishtest/varnishtest". Please build your varnish source directory])]
+)
+
+# vmod installation dir
+AC_ARG_VAR([VMODDIR], [vmod installation directory @<:@LIBDIR/varnish/vmods@:>@])
+if test "x$VMODDIR" = x; then
+ VMODDIR=`pkg-config --variable=vmoddir varnishapi`
+ if test "x$VMODDIR" = x; then
+ AC_MSG_FAILURE([Can't determine vmod installation directory])
+ fi
+fi
+
+AC_CONFIG_FILES([
+ Makefile
+ src/Makefile
+])
+AC_OUTPUT
View
0 README → m4/PLACEHOLDER
File renamed without changes.
View
28 src/Makefile.am
@@ -0,0 +1,28 @@
+INCLUDES = -I$(VARNISHSRC)/include -I$(VARNISHSRC)
+
+vmoddir = $(VMODDIR)
+vmod_LTLIBRARIES = libvmod_postparse.la
+
+libvmod_postparse_la_LDFLAGS = -module -export-dynamic -avoid-version
+
+libvmod_postparse_la_SOURCES = \
+ vcc_if.c \
+ vcc_if.h \
+ vmod_postparse.c
+
+vcc_if.c vcc_if.h: $(VARNISHSRC)/lib/libvmod_std/vmod.py $(top_srcdir)/src/vmod_postparse.vcc
+ @PYTHON@ $(VARNISHSRC)/lib/libvmod_std/vmod.py $(top_srcdir)/src/vmod_postparse.vcc
+
+VMOD_TESTS = tests/*.vtc
+.PHONY: $(VMOD_TESTS)
+
+tests/*.vtc:
+ $(VARNISHSRC)/bin/varnishtest/varnishtest -Dvarnishd=$(VARNISHSRC)/bin/varnishd/varnishd -Dvmod_topbuild=$(abs_top_builddir) $@
+
+check: $(VMOD_TESTS)
+
+EXTRA_DIST = \
+ vmod_postparse.vcc \
+ $(VMOD_TESTS)
+
+CLEANFILES = $(builddir)/vcc_if.c $(builddir)/vcc_if.h
View
31 src/tests/test01.vtc
@@ -0,0 +1,31 @@
+varnishtest "GET request"
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -vcl+backend {
+ import postparse from "${vmod_topbuild}/src/.libs/libvmod_postparse.so";
+
+ sub vcl_recv {
+ if(postparse.parse("X-TEST",true) == 1){
+ set req.http.x-run = "1";
+ }else{
+ set req.http.x-run = "0";
+ }
+ }
+ sub vcl_deliver{
+ set resp.http.x-run = req.http.x-run;
+ }
+} -start
+
+client c1 {
+ txreq -url "/"
+ rxresp
+ expect resp.http.x-run == "0"
+
+}
+
+
+client c1 -run
View
38 src/tests/test02.vtc
@@ -0,0 +1,38 @@
+varnishtest "POST request(url)"
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -vcl+backend {
+ import postparse from "${vmod_topbuild}/src/.libs/libvmod_postparse.so";
+
+ sub vcl_recv {
+ set req.http.x-run = postparse.parse("x-raw",true);
+ if(
+ req.http.a == "a" &&
+ req.http.b == "bb" &&
+ req.http.c == "ccc"
+ ){
+ set req.http.x-test = "1";
+ }
+ }
+ sub vcl_deliver{
+ set resp.http.x-run = req.http.x-run;
+ set resp.http.x-test = req.http.x-test;
+ set resp.http.x-raw = req.http.x-raw;
+ }
+} -start
+
+client c1 {
+ txreq -req POST -url "/" -hdr "Content-Type: application/x-www-form-urlencoded" -body "a=a&b=bb&c=ccc"
+ rxresp
+ expect resp.http.x-run == "1"
+ expect resp.http.x-test == "1"
+ expect resp.http.x-raw == "a=a&b=bb&c=ccc"
+
+}
+
+
+client c1 -run
View
38 src/tests/test02_x.vtc
@@ -0,0 +1,38 @@
+varnishtest "POST request(url) none head"
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -vcl+backend {
+ import postparse from "${vmod_topbuild}/src/.libs/libvmod_postparse.so";
+
+ sub vcl_recv {
+ set req.http.x-run = postparse.parse("",true);
+ if(
+ req.http.a == "a" &&
+ req.http.b == "bb" &&
+ req.http.c == "ccc" &&
+ !req.http.x-raw
+ ){
+ set req.http.x-test = "1";
+ }
+ }
+ sub vcl_deliver{
+ set resp.http.x-run = req.http.x-run;
+ set resp.http.x-test = req.http.x-test;
+ set resp.http.x-raw = req.http.x-raw;
+ }
+} -start
+
+client c1 {
+ txreq -req POST -url "/" -hdr "Content-Type: application/x-www-form-urlencoded" -body "a=a&b=bb&c=ccc"
+ rxresp
+ expect resp.http.x-run == "1"
+ expect resp.http.x-test == "1"
+
+}
+
+
+client c1 -run
View
38 src/tests/test03.vtc
@@ -0,0 +1,38 @@
+varnishtest "POST request(multipart)"
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -vcl+backend {
+ import postparse from "${vmod_topbuild}/src/.libs/libvmod_postparse.so";
+
+ sub vcl_recv {
+ set req.http.x-run = postparse.parse("x-raw",true);
+ if(
+ req.http.a == "a" &&
+ req.http.b == "bb" &&
+ req.http.c == "ccc"
+ ){
+ set req.http.x-test = "1";
+ }
+ }
+ sub vcl_deliver{
+ set resp.http.x-run = req.http.x-run;
+ set resp.http.x-test = req.http.x-test;
+ set resp.http.x-raw = req.http.x-raw;
+ }
+} -start
+
+client c1 {
+ txreq -req POST -url "/" -hdr "Content-Type: multipart/form-data; boundary=-----abcdef" -body "-------abcdef\r\nContent-Disposition: form-data; name=\"a\"\r\n\r\na\r\n-------abcdef\r\nContent-Disposition: form-data; name=\"b\"\r\n\r\nbb\r\n-------abcdef\r\nContent-Disposition: form-data; name=\"c\"\r\n\r\nccc\r\n-------abcdef--\r\n"
+ rxresp
+ expect resp.http.x-run == "1"
+ expect resp.http.x-test == "1"
+ expect resp.http.x-raw == "a=a&b=bb&c=ccc"
+
+}
+
+
+client c1 -run
View
38 src/tests/test03_x.vtc
@@ -0,0 +1,38 @@
+varnishtest "POST request(multipart)"
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -vcl+backend {
+ import postparse from "${vmod_topbuild}/src/.libs/libvmod_postparse.so";
+
+ sub vcl_recv {
+ set req.http.x-run = postparse.parse("",true);
+ if(
+ req.http.a == "a" &&
+ req.http.b == "bb" &&
+ req.http.c == "ccc" &&
+ !req.http.x-raw
+ ){
+ set req.http.x-test = "1";
+ }
+ }
+ sub vcl_deliver{
+ set resp.http.x-run = req.http.x-run;
+ set resp.http.x-test = req.http.x-test;
+ set resp.http.x-raw = req.http.x-raw;
+ }
+} -start
+
+client c1 {
+ txreq -req POST -url "/" -hdr "Content-Type: multipart/form-data; boundary=-----abcdef" -body "-------abcdef\r\nContent-Disposition: form-data; name=\"a\"\r\n\r\na\r\n-------abcdef\r\nContent-Disposition: form-data; name=\"b\"\r\n\r\nbb\r\n-------abcdef\r\nContent-Disposition: form-data; name=\"c\"\r\n\r\nccc\r\n-------abcdef--\r\n"
+ rxresp
+ expect resp.http.x-run == "1"
+ expect resp.http.x-test == "1"
+
+}
+
+
+client c1 -run
View
39 src/tests/test04.vtc
@@ -0,0 +1,39 @@
+varnishtest "POST request(multipart-file)"
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -vcl+backend {
+ import postparse from "${vmod_topbuild}/src/.libs/libvmod_postparse.so";
+
+ sub vcl_recv {
+ set req.http.x-run = postparse.parse("x-raw",true);
+ if(
+ req.http.a == "%e3%81%82+%e3%81%84'*-.%e3%81%be_%e3%81%86%e3%81%88%e3%81%8a" &&
+ req.http.b == "bb" &&
+ req.http.c == "ccc" &&
+ req.http.d == "ddd"
+ ){
+ set req.http.x-test = "1";
+ }
+ }
+ sub vcl_deliver{
+ set resp.http.x-run = req.http.x-run;
+ set resp.http.x-test = req.http.x-test;
+ set resp.http.x-raw = req.http.x-raw;
+ }
+} -start
+
+client c1 {
+ txreq -req POST -url "/" -hdr "Content-Type: multipart/form-data; boundary=-----abcdef" -body "-------abcdef\r\nContent-Disposition: form-data; name=\"a\"\r\n\r\nあ い'*-.ま_うえお\r\n-------abcdef\r\nContent-Disposition: form-data; name=\"b\"\r\n\r\nbb\r\n-------abcdef\r\nContent-Disposition: form-data; name=\"c\"\r\n\r\nccc\r\n-------abcdef\r\nContent-Disposition: form-data; name=\"d\"; filename=\"file.txt\"\r\nContent-Type: text/plain\r\n\r\nddd\r\n-------abcdef--"
+ rxresp
+ expect resp.http.x-run == "1"
+ expect resp.http.x-test == "1"
+ expect resp.http.x-raw == "a=%e3%81%82+%e3%81%84'*-.%e3%81%be_%e3%81%86%e3%81%88%e3%81%8a&b=bb&c=ccc&d=ddd"
+
+}
+
+
+client c1 -run
View
38 src/tests/test05.vtc
@@ -0,0 +1,38 @@
+varnishtest "POST request(multipart-file-noneparse)"
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -vcl+backend {
+ import postparse from "${vmod_topbuild}/src/.libs/libvmod_postparse.so";
+
+ sub vcl_recv {
+ set req.http.x-run = postparse.parse("x-raw",false);
+ if(
+ req.http.a == "a" &&
+ req.http.b == "bb" &&
+ req.http.c == "ccc"
+ ){
+ set req.http.x-test = "1";
+ }
+ }
+ sub vcl_deliver{
+ set resp.http.x-run = req.http.x-run;
+ set resp.http.x-test = req.http.x-test;
+ set resp.http.x-raw = req.http.x-raw;
+ }
+} -start
+
+client c1 {
+ txreq -req POST -url "/" -hdr "Content-Type: multipart/form-data; boundary=-----abcdef" -body "-------abcdef\r\nContent-Disposition: form-data; name=\"a\"\r\n\r\na\r\n-------abcdef\r\nContent-Disposition: form-data; name=\"b\"\r\n\r\nbb\r\n-------abcdef\r\nContent-Disposition: form-data; name=\"c\"\r\n\r\nccc\r\n-------abcdef\r\nContent-Disposition: form-data; name=\"d\"; filename=\"file.txt\"\r\nContent-Type: text/plain\r\n\r\nddd\r\n-------abcdef--"
+ rxresp
+ expect resp.http.x-run == "1"
+ expect resp.http.x-test == "1"
+ expect resp.http.x-raw == "a=a&b=bb&c=ccc"
+
+}
+
+
+client c1 -run
View
431 src/vmod_postparse.c
@@ -0,0 +1,431 @@
+#include <stdlib.h>
+#include "vcl.h"
+#include "vrt.h"
+#include "bin/varnishd/cache.h"
+#include <time.h>
+
+#include <arpa/inet.h>
+#include <syslog.h>
+#include <poll.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+#include "vcc_if.h"
+
+
+
+
+int
+init_function(struct vmod_priv *priv, const struct VCL_conf *conf)
+{
+ return (0);
+}
+
+
+unsigned __url_encode(char* url,int *calc,char *copy){
+ /*
+ base:http://d.hatena.ne.jp/hibinotatsuya/20091128/1259404695
+ */
+ int i;
+ char *pt = url;
+ unsigned char c;
+ char *url_en = copy;
+
+ for(i = 0; i < strlen(pt); ++i){
+ c = *url;
+
+ if((c >= '0' && c <= '9')
+ || (c >= 'A' && c <= 'Z')
+ || (c >= 'a' && c <= 'z')
+ || (c == '\'')
+ || (c == '*')
+ || (c == ')')
+ || (c == '(')
+ || (c == '-')
+ || (c == '.')
+ || (c == '_')){
+ *url_en = c;
+ ++url_en;
+ }else if(c == ' '){
+ *url_en = '+';
+ ++url_en;
+ }else{
+ *url_en = '%';
+ ++url_en;
+ sprintf(url_en, "%02x", c);
+ url_en = url_en + 2;
+ }
+ ++url;
+ }
+
+ *url_en = 0;
+ return(1);
+}
+unsigned url_encode_setHdr(struct sess *sp, char* url,char *head,int *encoded_size){
+ char *copy;
+ char buf[3075];
+ int size = 3 * strlen(url) + 3;
+ if(size > 3075){
+ ///////////////////////////////////////////////
+ //use ws
+ int u = WS_Reserve(sp->wrk->ws, 0);
+ if(u < size){
+ return 0;
+ }
+ copy = (char*)sp->wrk->ws->f;
+ ///////////////////////////////////////////////
+ }else{
+ copy = buf;
+ }
+ __url_encode(url,encoded_size,copy);
+
+ *encoded_size += strlen(copy) + head[0] +1;
+ if(size > 3075){
+ WS_Release(sp->wrk->ws,strlen(copy)+1);
+ }
+ //sethdr
+ VRT_SetHdr(sp, HDR_REQ, head, copy, vrt_magic_string_end);
+ return(1);
+}
+
+void decodeForm_multipart(struct sess *sp,char *body,char *tgHead,unsigned parseFile){
+
+ char tmp;
+ char head[256];
+ char sk_boundary[258];
+ char *raw_boundary, *h_ctype_ptr;
+ char *p_start, *p_end, *p_body_end, *name_line_end, *name_line_end_tmp, *start_body, *sc_name, *sc_filename;
+ int hsize, boundary_size ,idx;
+
+ char *tmpbody = body;
+ int encoded_size= 0;
+ char *basehead = 0;
+ char *curhead;
+ int ll_u, ll_head_len, ll_size;
+ int ll_entry_count = 0;
+
+ //////////////////////////////
+ //get boundary
+ h_ctype_ptr = VRT_GetHdr(sp, HDR_REQ, "\015Content-Type:");
+ raw_boundary = strstr(h_ctype_ptr,"; boundary=");
+ if(!raw_boundary || strlen(raw_boundary) > 255) return;
+ raw_boundary +=11;
+ sk_boundary[0] = '-';
+ sk_boundary[1] = '-';
+ sk_boundary[2] = 0;
+ strncat(sk_boundary,raw_boundary,strlen(raw_boundary));
+ boundary_size = strlen(sk_boundary);
+
+
+ p_start = strstr(tmpbody,sk_boundary);
+ while(1){
+ ///////////////////////////////////////////////
+ //search data
+
+ //boundary
+ p_end = strstr(p_start + 1,sk_boundary);
+ if(!p_end) break;
+ //name
+ sc_name = strstr(p_start +boundary_size,"name=\"");
+ if(!sc_name) break;
+ sc_name+=6;
+ //line end
+ name_line_end = strstr(sc_name,"\"\r\n");
+ name_line_end_tmp = strstr(sc_name,"\"; ");
+ if(!name_line_end) break;
+
+ if(name_line_end_tmp && name_line_end_tmp < name_line_end)
+ name_line_end = name_line_end_tmp;
+
+ //body
+ start_body = strstr(sc_name,"\r\n\r\n");
+ if(!start_body) break;
+ //filename
+ sc_filename = strstr(sc_name,"; filename");
+
+ ///////////////////////////////////////////////
+ //build head
+ if((name_line_end -1)[0]=='\\'){
+ idx = 1;
+ }else{
+ idx=0;
+ }
+ tmp = name_line_end[idx];
+ name_line_end[idx] = 0;
+ hsize = strlen(sc_name)+1;
+ if(hsize > 255) break;
+ head[0] = hsize;
+ head[1] = 0;
+ snprintf(head +1,255,"%s:",sc_name);
+ name_line_end[idx] = tmp;
+
+
+ ///////////////////////////////////////////////
+ //filecheck
+ if(!parseFile){
+ if(sc_filename && sc_filename < start_body){
+ //content is file(skip)
+ p_start = p_end;
+ continue;
+ }
+ }
+
+ ///////////////////////////////////////////////
+ //create linked list
+ //use ws
+ ll_u = WS_Reserve(sp->wrk->ws, 0);
+ ll_head_len = strlen(head +1) +1;
+ ll_size = ll_head_len + sizeof(char*)+2;
+ if(ll_u < ll_size){
+ return ;
+ }
+
+ if(!basehead){
+ curhead = (char*)sp->wrk->ws->f;
+ basehead = curhead;
+ }else{
+ ((char**)curhead)[0] = (char*)sp->wrk->ws->f;
+ curhead = (char*)sp->wrk->ws->f;
+ }
+ ++ll_entry_count;
+
+ memcpy(curhead,head,ll_head_len);
+ curhead +=ll_head_len;
+ memset(curhead,0,sizeof(char*)+1);
+ ++curhead;
+ WS_Release(sp->wrk->ws,ll_size);
+ ///////////////////////////////////////////////
+
+ ///////////////////////////////////////////////
+ //url encode & set header
+ p_body_end = p_end -2;
+ start_body +=4;
+ tmp = p_body_end[0];
+ p_body_end[0] = 0;
+ //bodyをURLエンコードする
+ if(!url_encode_setHdr(sp,start_body,head,&encoded_size)){
+ //メモリない
+ p_body_end[0] = tmp;
+ break;
+ }
+ p_body_end[0] = tmp;
+
+ ///////////////////////////////////////////////
+ //check last boundary
+ if(!p_end) break;
+
+ p_start = p_end;
+ }
+ if(tgHead[0] == NULL) return;
+
+ //////////////
+ //genarate x-www-form-urlencoded format data
+
+ //////////////
+ //use ws
+ int u = WS_Reserve(sp->wrk->ws, 0);
+ if(u < encoded_size + 1){
+ return;
+ }
+
+ char *orig_cv_body, *cv_body, *h_val;
+ orig_cv_body = cv_body = (char*)sp->wrk->ws->f;
+
+ WS_Release(sp->wrk->ws,encoded_size+1);
+ //////////////
+ for(int i=0;i<ll_entry_count;++i){
+ hsize = basehead[0];
+ memcpy(cv_body,basehead+1,hsize);
+ cv_body += hsize - 1;
+ cv_body[0] ='=';
+ ++cv_body;
+ h_val = VRT_GetHdr(sp,HDR_REQ,basehead);
+ memcpy(cv_body,h_val,strlen(h_val));
+ cv_body +=strlen(h_val);
+ cv_body[0] ='&';
+ ++cv_body;
+ basehead = *(char**)(basehead+strlen(basehead+1)+2);
+ }
+ orig_cv_body[encoded_size - 1] =0;
+
+ VRT_SetHdr(sp, HDR_REQ, tgHead, orig_cv_body, vrt_magic_string_end);
+
+}
+void decodeForm_urlencoded(struct sess *sp,char *body){
+ char head[256];
+ char *sc_eq,*sc_amp;
+ char *tmpbody = body;
+ int hsize;
+ char tmp;
+
+ while(1){
+ //////////////////////////////
+ //search word
+ if(!(sc_eq = strchr(tmpbody,'='))){
+ break;
+ }
+ if(!(sc_amp = strchr(tmpbody,'&'))){
+ sc_amp = sc_eq + strlen(tmpbody);
+ }
+
+ //////////////////////////////
+ //build head
+ tmp = sc_eq[0];
+ sc_eq[0] = 0;// = -> null
+
+ hsize = strlen(tmpbody) + 1;
+ if(hsize > 255) return;
+ head[0] = hsize;
+ head[1] = 0;
+ snprintf(head +1,255,"%s:",tmpbody);
+ sc_eq[0] = tmp;
+
+ //////////////////////////////
+ //build body
+ tmpbody = sc_eq + 1;
+ tmp = sc_amp[0];
+ sc_amp[0] = 0;// & -> null
+
+ //////////////////////////////
+ //set header
+ VRT_SetHdr(sp, HDR_REQ, head, tmpbody, vrt_magic_string_end);
+ sc_amp[0] = tmp;
+ tmpbody = sc_amp + 1;
+ }
+}
+int
+vmod_parse(struct sess *sp,const char* tgHeadName,unsigned parseFile){
+//デバッグでReInitとかrestartの時に不具合でないかチェック(ロールバックも)
+//Content = pipeline.e-bの時はRxbuf確保をしない(必要ないので)
+//mix形式をurlencodeに切り替える(組み換えで安全に)<-完了
+/*
+ string(41) "submitter\"=a&submitter2=b&submitter3=vcc"
+   string(42) "submitter%5C=a&submitter2=b&submitter3=vcc"
+  
+ string(39) "submitter=a&submitter2=b&submitter3=vcc"
+ string(39) "submitter=a&submitter2=b&submitter3=vcc"
+ string(83) "submitter=%e3%81%82%e3%81%84%e3%81%86%e3%81%88%e3%81%8a&submitter2=b&submitter3=vcc"
+ string(83) "submitter=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A&submitter2=b&submitter3=vcc"
+
+ 1 =成功
+ -1 =エラー ワークスペースサイズが足りない
+ -2 =エラー target/ContentLengthがない/不正
+ -3 =エラー 指定ContentLengthに満たないデータ
+ -4 =エラー 未対応形式
+ if (!(
+ !VRT_strcmp(VRT_r_req_request(sp), "POST") ||
+ !VRT_strcmp(VRT_r_req_request(sp), "PUT")
+ )){return "";}
+*/
+ unsigned long content_length,orig_content_length;
+ char *h_clen_ptr, *h_ctype_ptr, *body;
+ int buf_size, rsize;
+ char buf[1024],tgHead[256];
+ unsigned multipart = 0;
+
+
+
+ //////////////////////////////
+ //build tgHead
+ int hsize = strlen(tgHeadName) +1;
+ if(hsize > 1){
+ if(hsize > 255) return -2;
+ tgHead[0] = hsize;
+ tgHead[1] = 0;
+ snprintf(tgHead +1,255,"%s:",tgHeadName);
+ }else{
+ tgHead[0] = NULL;
+ }
+
+ //////////////////////////////
+ //check Content-Type
+ h_ctype_ptr = VRT_GetHdr(sp, HDR_REQ, "\015Content-Type:");
+
+ if (!VRT_strcmp(h_ctype_ptr, "application/x-www-form-urlencoded")) {
+ //application/x-www-form-urlencoded
+ }else if(h_ctype_ptr != NULL && h_ctype_ptr == strstr(h_ctype_ptr, "multipart/form-data")){
+ //multipart/form-data
+ multipart = 1;
+ }else{
+ //none support type
+ return -4;
+ }
+
+ //////////////////////////////
+ //check Content-Length
+ h_clen_ptr = VRT_GetHdr(sp, HDR_REQ, "\017Content-Length:");
+ if (!h_clen_ptr) {
+ //can't get
+ return -2;
+ }
+ orig_content_length = content_length = strtoul(h_clen_ptr, NULL, 10);
+
+ if (content_length <= 0) {
+ //illegal length
+ return -2;
+ }
+
+ //////////////////////////////
+ //Check POST data is loaded
+ if(sp->htc->pipeline.b != NULL && Tlen(sp->htc->pipeline) == content_length){
+ //complete read
+ body = sp->htc->pipeline.b;
+ }else{
+ //incomplete read
+
+ int rxbuf_size = Tlen(sp->htc->rxbuf);
+ ///////////////////////////////////////////////
+ //use ws
+ int u = WS_Reserve(sp->wrk->ws, 0);
+ if(u < content_length + rxbuf_size + 1){
+ return -1;
+ }
+ body = (char*)sp->wrk->ws->f;
+ memcpy(body, sp->htc->rxbuf.b, rxbuf_size);
+ sp->htc->rxbuf.b = body;
+ body += rxbuf_size;
+ body[0]= 0;
+ sp->htc->rxbuf.e = body;
+ WS_Release(sp->wrk->ws,content_length + rxbuf_size + 1);
+ ///////////////////////////////////////////////
+
+ //////////////////////////////
+ //read post data
+ while (content_length) {
+ if (content_length > sizeof(buf)) {
+ buf_size = sizeof(buf) - 1;
+ }
+ else {
+ buf_size = content_length;
+ }
+
+ // read body data into 'buf'
+ rsize = HTC_Read(sp->htc, buf, buf_size);
+
+ if (rsize <= 0) {
+ return -3;
+ }
+
+ hsize += rsize;
+ content_length -= rsize;
+
+ strncat(body, buf, buf_size);
+ }
+ sp->htc->pipeline.b = body;
+ sp->htc->pipeline.e = body + orig_content_length;
+ }
+
+
+ //////////////////////////////
+ //decode form
+ if(multipart){
+ decodeForm_multipart(sp, body,tgHead,parseFile);
+ }else{
+ if(tgHead[0] != NULL)
+ VRT_SetHdr(sp, HDR_REQ, tgHead, body, vrt_magic_string_end);
+ decodeForm_urlencoded(sp, body);
+ }
+ return 1;
+}
View
5 src/vmod_postparse.vcc
@@ -0,0 +1,5 @@
+Module postparse
+Init init_function
+
+Function INT parse(STRING,BOOL)
+

0 comments on commit c14e729

Please sign in to comment.
Something went wrong with that request. Please try again.