Changeset: cbe80f2740c7 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=cbe80f2740c7
Added Files:
common/stream/httpjson.c
common/stream/httpjson.h
Branch: Protobuf
Log Message:
httpjson utils
Unterschiede (gekürzt von 417 auf 300 Zeilen):
diff --git a/common/stream/httpjson.c b/common/stream/httpjson.c
new file mode 100644
--- /dev/null
+++ b/common/stream/httpjson.c
@@ -0,0 +1,352 @@
+#include "httpjson.h"
+#include <strings.h>
+#include "zlib.h"
+
+
+stream_export size_t httpjson_respond( stream* out, int code, char* message) {
+ char * status = "";
+ size_t len;
+ if (code == 400) {
+ status = "400 Bad Request";
+ }
+ if (code == 500) {
+ status = "500 Internal Server Error";
+ }
+ len = mnstr_printf(out,"HTTP/1.1 %s\r\nContent-Type:
text/plain\r\nContent-Length: %lu\r\n%s\r\n", status, strlen(message), message);
+ mnstr_flush(out);
+ mnstr_close(out);
+ return len;
+}
+#include "zlib.h"
+
+
+
+/* adapted from zlib/compress.c/compress2 */
+stream_export int gzipstring (char *dest, size_t *destLen, const char
*source, size_t sourceLen) {
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef *)source;
+ stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+ stream.next_out = (Bytef *)dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = deflateInit2 (&stream, Z_BEST_SPEED, Z_DEFLATED, (15 | 16), 8,
Z_DEFAULT_STRATEGY);
+ if (err != Z_OK) return err;
+
+ err = deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ deflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *destLen = stream.total_out;
+
+ err = deflateEnd(&stream);
+ return err;
+}
+
+
+
+stream_export void readHttpHeader(stream *in, char* headerbuf, size_t bufsize)
{
+ char cread;
+ size_t headerbufpos = 0;
+ /* read until we find \r\n\r\n or the header buffer is full */
+ while (mnstr_read(in, &cread, 1, 1) != 0 && headerbufpos < bufsize-1) {
+ headerbuf[headerbufpos] = cread;
+ if (headerbufpos > 4 &&
+ headerbuf[headerbufpos-3] == '\r' &&
+ headerbuf[headerbufpos-2] == '\n' &&
+ headerbuf[headerbufpos-1] == '\r' &&
+ headerbuf[headerbufpos] == '\n') {
+ headerbuf[headerbufpos+1] = '\0';
+ break;
+ }
+ headerbufpos++;
+ }
+}
+
+
+static void urldecode(char *dst, const char *src)
+{
+ char a, b;
+ while (*src) {
+ if ((*src == '%') &&
+ ((a = src[1]) && (b = src[2])) &&
+ (isxdigit(a) && isxdigit(b))) {
+ if (a >= 'a')
+ a -= 'a'-'A';
+ if (a >= 'A')
+ a -= ('A' - 10);
+ else
+ a -= '0';
+ if (b >= 'a')
+ b -= 'a'-'A';
+ if (b >= 'A')
+ b -= ('A' - 10);
+ else
+ b -= '0';
+ *dst++ = 16*a+b;
+ src+=3;
+ } else {
+ *dst++ = *src++;
+ }
+ }
+ *dst++ = '\0';
+}
+
+stream_export void parseUrlencodedBody(char* bodybuf, size_t bodybufsize,
http_query* out) {
+ size_t i;
+ int inLabel = 1;
+ char subfieldname[bodybufsize];
+ char * subfieldptr = subfieldname;
+ char subfieldvalue[bodybufsize];
+ char * subvalueptr = subfieldvalue;
+
+ for (i = 0; i < bodybufsize; i++) {
+ if (inLabel) {
+ if (bodybuf[i] == '=') {
+ inLabel = 0;
+ } else {
+ *subfieldptr = tolower(bodybuf[i]);
+ subfieldptr++;
+ }
+ } else {
+ *subvalueptr = bodybuf[i];
+ subvalueptr++;
+
+ }
+ if (bodybuf[i+1] == '&' || bodybuf[i+1] == '\0') {
+ *subfieldptr='\0';
+ *subvalueptr='\0';
+ if (strncmp(subfieldname, "query", 5) == 0) {
+ out->query = malloc(strlen(subfieldvalue));
+ urldecode(out->query, subfieldvalue);
+ }
+
+ subfieldptr = subfieldname;
+ subvalueptr = subfieldvalue;
+ memset(subfieldname, 0, bodybufsize);
+ memset(subfieldvalue, 0, bodybufsize);
+ inLabel = 1;
+ i++;
+ }
+ }
+}
+
+
+stream_export void parseDigestHeader(char* fieldbuf, size_t fieldbufsize,
http_digest_header* out) {
+ char subfieldname[fieldbufsize];
+ char * subfieldptr = subfieldname;
+ char subfieldvalue[fieldbufsize];
+ char * subvalueptr = subfieldvalue;
+
+ int inLabel = 1;
+ size_t i;
+ if (strncmp(fieldbuf, "Digest", 6) != 0) {
+ out->error = 1;
+ return;
+ }
+ out->username = NULL;
+ out->realm = NULL;
+ out->nonce = NULL;
+ out->uri = NULL;
+ out->cnonce = NULL;
+ out->nc = NULL;
+ out->qop = NULL;
+ out->response = NULL;
+
+
+ for (i = 7; i < fieldbufsize; i++) {
+ if (inLabel) {
+ if (fieldbuf[i] == '=') {
+ inLabel = 0;
+ } else {
+ *subfieldptr = tolower(fieldbuf[i]);
+ subfieldptr++;
+ }
+ } else {
+ if (fieldbuf[i] != '"') {
+ *subvalueptr = fieldbuf[i];
+ subvalueptr++;
+ }
+ }
+ if (fieldbuf[i+1] == ',' || fieldbuf[i+1] == '\r') {
+ *subfieldptr='\0';
+ *subvalueptr='\0';
+ if (strncmp(subfieldname, "username", 8) == 0) {
+ out->username = malloc(strlen(subfieldvalue));
+ strcpy(out->username, subfieldvalue);
+ }
+ if (strncmp(subfieldname, "realm", 5) == 0) {
+ out->realm = malloc(strlen(subfieldvalue));
+ strcpy(out->realm, subfieldvalue);
+ }
+ if (strncmp(subfieldname, "nonce", 5) == 0) {
+ out->nonce = malloc(strlen(subfieldvalue));
+ strcpy(out->nonce, subfieldvalue);
+ }
+ if (strncmp(subfieldname, "uri", 3) == 0) {
+ out->uri = malloc(strlen(subfieldvalue));
+ strcpy(out->uri, subfieldvalue);
+ }
+ if (strncmp(subfieldname, "cnonce", 6) == 0) {
+ out->cnonce = malloc(strlen(subfieldvalue));
+ strcpy(out->cnonce, subfieldvalue);
+ }
+ if (strncmp(subfieldname, "nc", 2) == 0) {
+ out->nc = malloc(strlen(subfieldvalue));
+ strcpy(out->nc, subfieldvalue);
+ }
+ if (strncmp(subfieldname, "qop", 2) == 0) {
+ out->qop = malloc(strlen(subfieldvalue));
+ strcpy(out->qop, subfieldvalue);
+ }
+ if (strncmp(subfieldname, "response", 8) == 0) {
+ out->response = malloc(strlen(subfieldvalue));
+ strcpy(out->response, subfieldvalue);
+ }
+
+ subfieldptr = subfieldname;
+ subvalueptr = subfieldvalue;
+ memset(subfieldname, 0, fieldbufsize);
+ memset(subfieldvalue, 0, fieldbufsize);
+ inLabel = 1;
+ i+=2; // TODO: always a space behind the ,?
+ }
+ }
+ out->error = out->username == NULL ||
+ out->realm == NULL ||
+ out->nonce == NULL ||
+ out->uri == NULL ||
+ out->cnonce == NULL ||
+ out->nc == NULL ||
+ out->qop == NULL ||
+ out->response == NULL;
+}
+
+stream_export void getHeader(char* headerbuf, size_t bufsize, char* fieldbuf,
size_t fieldbufsize, char* whichfield) {
+ size_t fieldbufpos = 0;
+ size_t i;
+ int thisline = 0;
+ char fieldcache[fieldbufsize];
+
+ char * cpos;
+ for (i = 0; i < bufsize-1 && fieldbufpos < fieldbufsize-1; i++) {
+ fieldbuf[fieldbufpos] = headerbuf[i];
+ if (strncmp(fieldbuf, whichfield, strlen(whichfield)) == 0) {
+ thisline = 1;
+ }
+ /* if we are at the end of the header line... */
+ if (fieldbuf[fieldbufpos-1] == '\r' &&
+ fieldbuf[fieldbufpos] == '\n') {
+ if (thisline) {
+ /* we read the correct line into fieldbuf */
+ break;
+ }
+ else {
+ /* ignore this field, overwrite */
+ fieldbufpos = 0;
+ }
+ }
+ else {
+ fieldbufpos++;
+ }
+ }
+ /* We did not find our field, return NULL */
+ if (!thisline) {
+ fieldbuf = NULL;
+ return;
+ }
+ /* make sure fieldbuf is terminated */
+ fieldbuf[fieldbufpos+1] = '\0';
+ /* find first :, it separates the field name from the field value */
+
+ cpos = strchr(fieldbuf, ':');
+ if (cpos == NULL) {
+ fieldbuf = NULL;
+ return;
+ }
+ /* advance beyond ':' */
+ cpos++;
+
+ /* trim leading white space from field value */
+ while(isspace(*cpos)) cpos++;
+ strcpy(fieldcache, cpos);
+ strcpy(fieldbuf, fieldcache);
+}
+
+
+/*
+ *
+ * struct line {
+ char *field;
+ size_t field_len;
+ char *value;
+ size_t value_len;
+};
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list