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

Reply via email to