The fix to have everything binary related working.newparser
authorStefan de Konink <stefan@konink.de>
Sun, 21 Nov 2010 16:13:28 +0000 (21 17:13 +0100)
committerStefan de Konink <stefan@konink.de>
Sun, 21 Nov 2010 16:13:28 +0000 (21 17:13 +0100)
mistral.c

index 87b1ab4..caabff0 100644 (file)
--- a/mistral.c
+++ b/mistral.c
@@ -42,6 +42,7 @@ struct client {
        struct ev_loop *loop;
        char *rbuff;
        int rlen;
+       int done;
 
        int close;
 };
@@ -65,7 +66,7 @@ void http_field_cb(void *data, const char *field, size_t flen, const char *value
        char *val = strndup(value, vlen);
        size_t i;
 
-       strncpy(fld, "HTTP_", 5);
+       memcpy(fld, "HTTP_", 5);
        for (i = 0; i < flen; i++) {
                if (field[i] == '-')
                        fld[5+i] = '_';
@@ -166,6 +167,8 @@ static void goodbye_cb(struct ev_loop *loop, struct ev_timer *w, int revents) {
        ev_io_stop(loop, &cli->ev_write);
        ev_timer_stop(loop, &cli->ev_timeout);
 
+       shutdown(cli->fd, SHUT_WR);
+
        close(cli->fd);
        free(cli);
 }
@@ -181,17 +184,23 @@ static void write_cb(struct ev_loop *loop, struct ev_io *w, int revents)
 
        if (revents & EV_WRITE) {
                if (cli->rbuff) {
-                       write(cli->fd, cli->rbuff, cli->rlen);
-                       free(cli->rbuff);
+                       cli->done += write(cli->fd, cli->rbuff + cli->done, cli->rlen - cli->done);
+                       if (cli->done == cli->rlen) {
+                               free(cli->rbuff);
+                               cli->rbuff = NULL;
+                               cli->rlen = 0;
+                       } 
                }
                ev_io_stop(EV_A_ w);
        }
 
-       if (cli->close == 1 || timeout == 0.0) {
+       if ((cli->rlen == 0 && cli->close == 1) || timeout == 0.0) {
                ev_timer_start(loop, &cli->ev_goodbye);
        } else {
                ev_timer_again(loop, &cli->ev_timeout);
                ev_io_start(loop, &cli->ev_read);
+               if (cli->done < cli->rlen)
+                       ev_io_start(loop, &cli->ev_write);
        }
 }
 
@@ -203,6 +212,7 @@ static inline void* execute_php(void *_cli) {
         MAKE_STD_ZVAL(headers[0]);
         array_init(headers[0]);
 
+               cli->done = 0;
         cli->rbuff[cli->rlen] = '\0';
 
         http_parser_init(&parser);
@@ -251,7 +261,7 @@ static inline void* execute_php(void *_cli) {
 
                                        if (Z_STRLEN(temp) > 0) {
                                                if (php_strcmp("status_code", key, key_len - 1)) {
-                                                       status_code = strdup(Z_STRVAL(temp));
+                                                       status_code = strndup(Z_STRVAL(temp), Z_STRLEN(temp));
                                                        status_len += Z_STRLEN(temp);
                                                } else if (php_strcmp("body", key, key_len - 1)) {
                                                        body_len += Z_STRLEN(temp);
@@ -274,14 +284,16 @@ static inline void* execute_php(void *_cli) {
                        test = cli->rbuff;
 
                        if (status_len == 0) {
-                               strncpy(test, "HTTP/1.1 200 OK\r\n", 17);
+                               memcpy(test, "HTTP/1.1 200 OK\r\n", 17);
                                test += 17;
                        } else {
-                               strncpy(test, "HTTP/1.1 ", 9);
+                               memcpy(test, "HTTP/1.1 ", 9);
                                test += 9;
-                               strncpy(test, status_code, status_len);
+                               
+                               memcpy(test, status_code, status_len);
                                test += status_len;
-                               strncpy(test, "\r\n", 2);
+                               
+                               memcpy(test, "\r\n", 2);
                                test += 2;
                                free(status_code);
                        }
@@ -302,15 +314,19 @@ static inline void* execute_php(void *_cli) {
                                                if (status_len > 0 && php_strcmp("status_code", key, key_len - 1)) {
                                                        /* do nothing */
                                                } else if (body_len > 0 && php_strcmp("body", key, key_len - 1)) {
-                                                       body = strdup(Z_STRVAL(temp));
+                                                       body = malloc(Z_STRLEN(temp) * sizeof(char));
+                                                       memcpy(body, Z_STRVAL(temp), Z_STRLEN(temp));
                                                } else { /* So it is a header */
-                                                       strncpy(test, key, key_len - 1);
-                                                       test += key_len - 1;
-                                                       strncpy(test, ": ", 2);
+                                                       memcpy(test, key, key_len - 1);
+                                                       test += (key_len - 1);
+                                                       
+                                                       memcpy(test, ": ", 2);
                                                        test += 2;
-                                                       strncpy(test, Z_STRVAL(temp), Z_STRLEN(temp));
+                                                       
+                                                       memcpy(test, Z_STRVAL(temp), Z_STRLEN(temp));
                                                        test += Z_STRLEN(temp);
-                                                       strncpy(test, "\r\n", 2);
+                                                       
+                                                       memcpy(test, "\r\n", 2);
                                                        test += 2;
                                                }
                                        }
@@ -318,11 +334,11 @@ static inline void* execute_php(void *_cli) {
                                }
                        }
 
-                       strncpy(test, "\r\n", 2);
+                       memcpy(test, "\r\n", 2);
                        test += 2;
 
                        if (body) {
-                               strncpy(test, body, body_len);
+                               memcpy(test, body, body_len);
                                free(body);
                                test += body_len;
                        }
@@ -513,7 +529,7 @@ PHP_FUNCTION(mistral_init)
                case AF_INET:
                        if ( strchr(listen_addr, ':') )
                                /* Invalid IPv4-string. Use the wildcard address. */
-                               listen_addr = strdup("0.0.0.0");
+                               listen_addr = strndup("0.0.0.0", 7);
 
                        inet_pton(sin.ss_family, listen_addr, &(sa4->sin_addr));
                        sa4->sin_port = htons(listen_port);