Giter VIP home page Giter VIP logo

qdecoder's Introduction

What's qDecoder?

qDecoder is a CGI library for C/C++ programming language which has been developed since 1996.

Features

  • Supports parsing a request encoded by GET/POST method
  • Supports parsing multipart/form-data encoding. (in-memory and direct disk)
  • Supports COOKIE handling.
  • Supports Session management.
  • Supports FastCGI

API Reference

API Reference

How easy making CGI applications in C/C++

[HTML example]

  <form action="your_program.cgi">
    <input type="text" name="color">
    <input type="submit">
  </form>

[Code example]

  qentry_t *req = qcgireq_parse(NULL, 0);

  qcgires_setcontenttype(req, "text/plain");
  const char *color = req->getstr(req, "color", false);
  if (color != NULL) {
    printf("color = %s\n", color);
  }

  req->free(req);

The order of parsing sequence is (1)COOKIE (2)POST (3)GET. Thus if there is a same query name existing in different methods, COOKIE values will be stored first than POST, GET values will be added at the very last into a qentry linked-list.

Below is an example to parse only two given methods. Please note that when multiple methods are specified, it'll be parsed in the order of COOKIE, POST and GET.

  qentry_t *req = qcgireq_parse(req, Q_CGI_COOKIE | Q_CGI_POST);

To change the order of parsing sequence, you can call qcgireq_parse() multiple times in the order that you want as below.

  qentry_t *req;
  req = qcgireq_parse(req, Q_CGI_POST);
  req = qcgireq_parse(req, Q_CGI_GET);
  req = qcgireq_parse(req, Q_CGI_COOKIE);

In terms of multipart/form-data encoding(used for file uploading), qDecoder can handle that in two different ways internally.

  • default mode : Uploading file will be processed only in memory. (see examples/upload.c)
  • file mode : Uploading file will be stored directly into disk. (see examples/uploadfile.c)

You can switch to file mode by calling qCgiRequestSetOption().

  Q_ENTRY *req = qcgireq_setoption(NULL, true, "/tmp", 86400);
  req = qcgireq_parse(req, 0);
  // ...your codes here...
  req->free(req);

Basically, when file is uploaded qDecoder store it's meta information like below.

  • (VARIABLE_NAME) - In the default mode, this is binary data. In the file mode this value is same as "(VARIABLE_NAME).savepath".
  • (VARIABLE_NAME).filename - File name itself, path information will be removed.
  • (VARIABLE_NAME).length - File size, the number of bytes.
  • (VARIABLE_NAME).contenttype - Mime type like 'text/plain'.
  • (VARIABLE_NAME).savepath - Only appended only in file mode. The file path where the uploaded file is saved.
  [default mode example]
  binary = (...binary data...)
  binary.filename = hello.xls
  binary.length = 3292
  binary.contenttype = application/vnd.ms-excel

  [file mode example]
  binary = tmp/q_wcktIq
  binary.length = 60014
  binary.filename = hello.xls
  binary.contenttype = application/vnd.ms-excel
  binary.savepath = tmp/q_wcktIq

Please refer the examples included in the source package for more detailed samples.

Contributors

The following people have helped with suggestions, ideas, code or fixing bugs: (in alphabetical order by first name)

If we have forgotten your name or spelled not in the way you want, please let us know.

qdecoder's People

Contributors

ffontaine avatar jwendell avatar ktd2004 avatar nyov avatar weongyo avatar wolkykim avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qdecoder's Issues

Makefile.in not using DESTDIR for install target

Makefile.in in src directory does not make use of DESTDIR for install target.

Which creates issue in package creation in Arch linux. (and may be will create issues in other distribution too)
https://aur.archlinux.org/packages/qdecoder/

For more information on DESTDIR please see:
https://www.gnu.org/prep/standards/html_node/DESTDIR.html

DESTDIR support is commonly used in package creation.

Small patch for using DESTDIR is here:
http://pastebin.com/raw/upaCqKex

Please consider patching.

Thank you

get a CVE for fixed security vulnerability

Hello @wolkykim

Thanks for this project. The PR #29 seems to address a security vulnerability that could lead to RCE. Seems like no CVE was assigned. Can you please get one. If you would like help I am happy to help write up CVE and submit also on your behalf.

You could use Vulnogram project https://vulnogram.github.io/#editor to create a CVE or hand craft it if needed. Use CVE form to submit the CVE.

Thanks
Vijay

enable-fastcgi should be a flag instead of an absolute path?

can enable-fastcgi be just a flag, or even better, just the way like: enable-fastcgi / disable-fastcgi (default can be disable-fastcgi), this is the "typical" autotools way anyways.

otherwise, with an absolute path, enable-fastcgi will cause trouble in cross-compiling.

Makefile on Debian

You have an absolute path to programs like /usr/bin/mkdir in src/Makefile, but in Debian, there are no such a files. In Debian there is /bin/mkdir (rm, rmdir) .

I also have to run ldconfig after "make install" witch should by describen in an INSTALL.md file.

Otherwise everything works perfekt :)

Installation failure after configuring with the --prefix option.

A clone of the master branch at commit 63888fc fails to install under Linux when the configure script's --prefix option is used.

System info:

$ uname -a
Linux test 3.14-2-amd64 #1 SMP Debian 3.14.15-2 (2014-08-09) x86_64 GNU/Linux
$ gcc --version
gcc (Debian 4.9.1-11) 4.9.1
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ 

Ran the configure script like:

$ ./configure --prefix=/opt/qdecoder

Compiled it successfully like:

$ make
===> src
make[1]: Entering directory '/tmp/qdecoder/src'
gcc -std=gnu99 -Wall -fPIC -g -I/usr/include -I/usr/local/include -I./ -D_GNU_SOURCE -c -o qcgireq.o qcgireq.c
gcc -std=gnu99 -Wall -fPIC -g -I/usr/include -I/usr/local/include -I./ -D_GNU_SOURCE -c -o qcgires.o qcgires.c
gcc -std=gnu99 -Wall -fPIC -g -I/usr/include -I/usr/local/include -I./ -D_GNU_SOURCE -c -o qcgisess.o qcgisess.c
gcc -std=gnu99 -Wall -fPIC -g -I/usr/include -I/usr/local/include -I./ -D_GNU_SOURCE -c -o qentry.o qentry.c
gcc -std=gnu99 -Wall -fPIC -g -I/usr/include -I/usr/local/include -I./ -D_GNU_SOURCE -c -o internal.o internal.c
/usr/bin/ar -rc libqdecoder.a qcgireq.o qcgires.o qcgisess.o qentry.o internal.o
ranlib libqdecoder.a
gcc -std=gnu99 -shared -Wl,-soname,libqdecoder.so.12 -o libqdecoder.so.12 qcgireq.o qcgires.o qcgisess.o qentry.o internal.o
ln -s -f libqdecoder.so.12 libqdecoder.so
make[1]: Leaving directory '/tmp/qdecoder/src'
<=== src

But the installation fails:

$ sudo make install
(cd src/; make install)
make[1]: Entering directory '/tmp/qdecoder/src'
/usr/bin/ar -rc libqdecoder.a qcgireq.o qcgires.o qcgisess.o qentry.o internal.o
ranlib libqdecoder.a
gcc -std=gnu99 -shared -Wl,-soname,libqdecoder.so.12 -o libqdecoder.so.12 qcgireq.o qcgires.o qcgisess.o qentry.o internal.o
ln -s -f libqdecoder.so.12 libqdecoder.so
/usr/bin/install -c -m 644 qdecoder.h /opt/qdecoder/include/qdecoder.h
/usr/bin/install: cannot create regular file ‘/opt/qdecoder/include/qdecoder.h’: No such file or directory
Makefile:81: recipe for target 'install' failed
make[1]: *** [install] Error 1
make[1]: Leaving directory '/tmp/qdecoder/src'
Makefile:41: recipe for target 'install' failed
make: *** [install] Error 2
$ 

Compilation failure after configuring with --enable-debug.

A clone of the master branch at commit 63888fc fails to build under Linux with GCC 4.9 when the configure script's --enable-debug option is used.

System info:

$ uname -a
Linux test 3.14-2-amd64 #1 SMP Debian 3.14.15-2 (2014-08-09) x86_64 GNU/Linux
$ gcc --version
gcc (Debian 4.9.1-11) 4.9.1
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ 

Ran the configure script like:

$ ./configure --enable-debug

Compilation error:

$ make
===> src
make[1]: Entering directory '/tmp/qdecoder/src'
gcc -std=gnu99 -Wall -fPIC -g -I/usr/include -I/usr/local/include -I./ -D_GNU_SOURCE -DBUILD_DEBUG -c -o qcgireq.o qcgireq.c
In file included from qcgireq.c:143:0:
qcgireq.c: In function ‘_parse_multipart_value_into_disk’:
qcgireq.c:738:60: error: ‘errno’ undeclared (first use in this function)
         DEBUG("I/O error. (errno=%d)", (ioerror == true) ? errno : 0);
                                                            ^
internal.h:38:76: note: in definition of macro ‘DEBUG’
 #define DEBUG(fmt, args...) fprintf(stderr, "[DEBUG] " fmt " (%s:%d)\n", ##args, __FILE__, __LINE__);
                                                                            ^
qcgireq.c:738:60: note: each undeclared identifier is reported only once for each function it appears in
         DEBUG("I/O error. (errno=%d)", (ioerror == true) ? errno : 0);
                                                            ^
internal.h:38:76: note: in definition of macro ‘DEBUG’
 #define DEBUG(fmt, args...) fprintf(stderr, "[DEBUG] " fmt " (%s:%d)\n", ##args, __FILE__, __LINE__);
                                                                            ^
Makefile:104: recipe for target 'qcgireq.o' failed
make[1]: *** [qcgireq.o] Error 1
make[1]: Leaving directory '/tmp/qdecoder/src'
<=== src
$ 

some trouble linking the examples

I'm trying to build with FastCGI support, and it does, but the examples not.
This is probably a luser error on my end, but I can't figure it out.

In ./examples;

$ /usr/bin/make clean

$ /usr/bin/make query.cgi
gcc -std=gnu99 -Wall -fPIC -g -I../src/  -I/usr/include -I/usr/local/include -I./ -D_GNU_SOURCE -DENABLE_FASTCGI -I/usr/include -c -o query.o query.c
gcc -std=gnu99 -Wall -fPIC -g -I../src/  -I/usr/include -I/usr/local/include -I./ -D_GNU_SOURCE -DENABLE_FASTCGI -I/usr/include -o query.cgi query.o ../src/libqdecoder.a 
../src/libqdecoder.a(qcgireq.o): In function `qcgireq_getquery':
/tmp/qdecoder.git/src/qcgireq.c:333: undefined reference to `_fcgi_sF'
/tmp/qdecoder.git/src/qcgireq.c:333: undefined reference to `FCGI_fgetc'
../src/libqdecoder.a(qcgireq.o): In function `_parse_multipart':
/tmp/qdecoder.git/src/qcgireq.c:405: undefined reference to `_fcgi_sF'
/tmp/qdecoder.git/src/qcgireq.c:432: undefined reference to `_fcgi_sF'
../src/libqdecoder.a(qcgireq.o): In function `_parse_multipart_value_into_memory':
/tmp/qdecoder.git/src/qcgireq.c:551: undefined reference to `_fcgi_sF'
/tmp/qdecoder.git/src/qcgireq.c:551: undefined reference to `FCGI_fgetc'
../src/libqdecoder.a(qcgireq.o): In function `_parse_multipart_value_into_disk':
/tmp/qdecoder.git/src/qcgireq.c:667: undefined reference to `_fcgi_sF'
/tmp/qdecoder.git/src/qcgireq.c:667: undefined reference to `FCGI_fgetc'
../src/libqdecoder.a(qcgires.o): In function `qcgires_setcookie':
/tmp/qdecoder.git/src/qcgires.c:121: undefined reference to `FCGI_printf'
../src/libqdecoder.a(qcgires.o): In function `qcgires_setcontenttype':
/tmp/qdecoder.git/src/qcgires.c:171: undefined reference to `FCGI_printf'
../src/libqdecoder.a(qcgires.o): In function `qcgires_redirect':
/tmp/qdecoder.git/src/qcgires.c:216: undefined reference to `FCGI_printf'
../src/libqdecoder.a(qcgires.o): In function `qcgires_download':
/tmp/qdecoder.git/src/qcgires.c:262: undefined reference to `FCGI_printf'
/tmp/qdecoder.git/src/qcgires.c:263: undefined reference to `FCGI_printf'
../src/libqdecoder.a(qcgires.o):/tmp/qdecoder.git/src/qcgires.c:264: more undefined references to `FCGI_printf' follow
../src/libqdecoder.a(qcgires.o): In function `qcgires_download':
/tmp/qdecoder.git/src/qcgires.c:271: undefined reference to `_fcgi_sF'
/tmp/qdecoder.git/src/qcgires.c:271: undefined reference to `FCGI_fflush'
/tmp/qdecoder.git/src/qcgires.c:273: undefined reference to `_fcgi_sF'
/tmp/qdecoder.git/src/qcgires.c:273: undefined reference to `FCGI_fileno'
../src/libqdecoder.a(qcgires.o): In function `qcgires_error':
/tmp/qdecoder.git/src/qcgires.c:300: undefined reference to `FCGI_printf'
/tmp/qdecoder.git/src/qcgires.c:304: undefined reference to `FCGI_printf'
/tmp/qdecoder.git/src/qcgires.c:305: undefined reference to `FCGI_printf'
/tmp/qdecoder.git/src/qcgires.c:306: undefined reference to `FCGI_printf'
/tmp/qdecoder.git/src/qcgires.c:307: undefined reference to `FCGI_printf'
../src/libqdecoder.a(qcgires.o):/tmp/qdecoder.git/src/qcgires.c:308: more undefined references to `FCGI_printf' follow
../src/libqdecoder.a(qentry.o): In function `_save':
/tmp/qdecoder.git/src/qentry.c:743: undefined reference to `FCGI_fopen'
/tmp/qdecoder.git/src/qentry.c:749: undefined reference to `FCGI_fileno'
/tmp/qdecoder.git/src/qentry.c:751: undefined reference to `FCGI_fprintf'
/tmp/qdecoder.git/src/qentry.c:752: undefined reference to `FCGI_fprintf'
/tmp/qdecoder.git/src/qentry.c:757: undefined reference to `FCGI_fprintf'
/tmp/qdecoder.git/src/qentry.c:761: undefined reference to `FCGI_fclose'
../src/libqdecoder.a(qentry.o): In function `_load':
/tmp/qdecoder.git/src/qentry.c:778: undefined reference to `FCGI_fopen'
../src/libqdecoder.a(qentry.o): In function `_print':
/tmp/qdecoder.git/src/qentry.c:813: undefined reference to `FCGI_fprintf'
../src/libqdecoder.a(internal.o): In function `_q_fgets':
/tmp/qdecoder.git/src/internal.c:163: undefined reference to `FCGI_fgetc'
../src/libqdecoder.a(internal.o): In function `_q_fgetline':
/tmp/qdecoder.git/src/internal.c:185: undefined reference to `FCGI_fgetc'
collect2: error: ld returned 1 exit status
make: *** [query.cgi] Error 1

Here is everything I've done before that.

Libs are installed; in /usr/include

# dpkg -L libfcgi-dev
/.
/usr
/usr/share
/usr/share/doc
/usr/share/doc/libfcgi-dev
/usr/share/doc/libfcgi-dev/changelog.Debian.gz
/usr/share/doc/libfcgi-dev/copyright
/usr/lib
/usr/lib/libfcgi++.a
/usr/lib/libfcgi.a
/usr/lib/libfcgi.la
/usr/lib/libfcgi++.la
/usr/include
/usr/include/fcgios.h
/usr/include/fcgio.h
/usr/include/fcgimisc.h
/usr/include/fcgiapp.h
/usr/include/fcgi_stdio.h
/usr/include/fcgi_config.h
/usr/include/fastcgi.h
/lib
/usr/lib/libfcgi.so
/usr/lib/libfcgi++.so

configure with /usr/include as path

$ ./configure --enable-fastcgi=/usr/include
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for gcc option to accept ISO C99... -std=gnu99
checking for a BSD-compatible install... /usr/bin/install -c
checking whether ln -s works... yes
checking whether make sets $(MAKE)... yes
checking for ranlib... ranlib
checking for ar... /usr/bin/ar
checking for chmod... /bin/chmod
checking for ld... /usr/bin/ld
checking for rm... /bin/rm
checking how to run the C preprocessor... gcc -std=gnu99 -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for stdbool.h that conforms to C99... yes
checking for _Bool... yes
checking for dirent.h that defines DIR... yes
checking for library containing opendir... none required
checking for size_t... yes
checking for off_t... yes
checking for /usr/include/fcgi_stdio.h... yes
configure: 'fastcgi' feature is enabled
configure: CFLAGS -Wall -fPIC -g
configure: CPPFLAGS  -I/usr/include -I/usr/local/include -I./ -D_GNU_SOURCE -DENABLE_FASTCGI -I/usr/include
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating examples/Makefile
config.status: creating config.h

make looks good;

$ /usr/bin/make
===> src
make[1]: Entering directory `/tmp/qdecoder.git/src'
gcc -std=gnu99 -Wall -fPIC -g -I/usr/include -I/usr/local/include -I./ -D_GNU_SOURCE -DENABLE_FASTCGI -I/usr/include -c -o qcgireq.o qcgireq.c
gcc -std=gnu99 -Wall -fPIC -g -I/usr/include -I/usr/local/include -I./ -D_GNU_SOURCE -DENABLE_FASTCGI -I/usr/include -c -o qcgires.o qcgires.c
gcc -std=gnu99 -Wall -fPIC -g -I/usr/include -I/usr/local/include -I./ -D_GNU_SOURCE -DENABLE_FASTCGI -I/usr/include -c -o qcgisess.o qcgisess.c
gcc -std=gnu99 -Wall -fPIC -g -I/usr/include -I/usr/local/include -I./ -D_GNU_SOURCE -DENABLE_FASTCGI -I/usr/include -c -o qentry.o qentry.c
gcc -std=gnu99 -Wall -fPIC -g -I/usr/include -I/usr/local/include -I./ -D_GNU_SOURCE -DENABLE_FASTCGI -I/usr/include -c -o internal.o internal.c
/usr/bin/ar -rc libqdecoder.a qcgireq.o qcgires.o qcgisess.o qentry.o internal.o
ranlib libqdecoder.a
gcc -std=gnu99 -shared -Wl,-soname,libqdecoder.so.12 -o libqdecoder.so.12 qcgireq.o qcgires.o qcgisess.o qentry.o internal.o
ln -s -f libqdecoder.so.12 libqdecoder.so
make[1]: Leaving directory `/tmp/qdecoder.git/src'
<=== src

make install'ed into /usr/local/lib|include/ as well.

My /usr/include/fcgi_stdio.h looks like it should.
I don't see why it's not found, which is the issue here I believe?
Thanks for any pointers.

CRLF and FastCGI compatibility

(cont. from #2)
regarding a3277e9,
the CRLF fix works, I wasn't sure if it's really necessary after every header, but it seems to be the right thing to do, as the RFC defines it.

regarding 58e6191,
fwrite() doesn't fix the download so far, but your use of fdopen looks close to my own try, so I'll try to make it work and let you know.

CGI program sent malformed headers

Running the examples, I got this kind of return stating the headers are malformed:

Error 500: Internal Server Error
Error: CGI program sent malformed or too big (>16384 bytes) HTTP headers: [Content-Type: text/html

You entered: <b>test</b>
]

So, I just added a newline after call to qcgires_setcontenttype() in the examples, recompiled and then, no more error!

E.G. in examples/query.c:52, I just added "\n" at beginning of printed string after headers:

    // Print out
    qcgires_setcontenttype(req, "text/html");
    printf("\nYou entered: <b>%s</b>\n", value);

Tested in Windows 7 64-bit w/ qDecoder 12.0.7 built against native MinGW64 4.7 (TDM flavor) and CivetWeb web server.

linking issue

I know I am screwing up, but I am not sure where. When I try to build I keep getting the following error:
return_search.c:(.text+0x3d): undefined reference to `qcgireq_parse'

I am building using the following line:
gcc -o return_search.ac return_search.c $(pkg-config --cflags --libs libmongoc-1.0) -lfcgi -I I/usr/include -o qdecoder/src/libqdecoder.a

Thanks

repository with SVN history

@wolkykim, I have created a git repo with the old subversion history and tags included.
It's at https://github.com/nyov/qdecoder/. If you care for that, I would push it here.

The problem is this would break all the forks and clones once, because the history changed and all the SHA1 commit ID's don't match anymore. People will have to force-update their clones.

But doing this now, while there aren't that many forks yet, I think in the long run it would be better to have the history.

cannot check for file existence when cross compiling

When I set enable-fcgi under a cross compile it will fail, can configure honor cross compiling?

if test "$enableval" = yes; then
        as_ac_File=`$as_echo "ac_cv_file_$enable_fastcgi/fcgi_stdio.h" | $as_tr_sh`
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $enable_fastcgi/fcgi_stdio.h" >&5
$as_echo_n "checking for $enable_fastcgi/fcgi_stdio.h... " >&6; }
if eval \${$as_ac_File+:} false; then :
  $as_echo_n "(cached) " >&6
else
  test "$cross_compiling" = yes &&
  as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
if test -r "$enable_fastcgi/fcgi_stdio.h"; then
  eval "$as_ac_File=yes"
else
  eval "$as_ac_File=no"
fi
fi

New release ?

Hello,

Could you make a new release? I would like to use it in buildroot.

Thanks,

Fabrice

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.