/[jscoverage]/trunk/jscoverage-server.c
ViewVC logotype

Diff of /trunk/jscoverage-server.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 179 by siliconforks, Sun Sep 21 18:35:21 2008 UTC revision 275 by siliconforks, Sat Oct 11 22:38:05 2008 UTC
# Line 237  Line 237 
237    return result;    return result;
238  }  }
239    
240    static unsigned int hex_value(char c) {
241      if ('0' <= c && c <= '9') {
242        return c - '0';
243      }
244      else if ('A' <= c && c <= 'F') {
245        return c - 'A' + 10;
246      }
247      else if ('a' <= c && c <= 'f') {
248        return c - 'a' + 10;
249      }
250      else {
251        return 0;
252      }
253    }
254    
255    static char * decode_uri_component(const char * s) {
256      size_t length = strlen(s);
257      char * result = xmalloc(length + 1);
258      char * p = result;
259      while (*s != '\0') {
260        if (*s == '%') {
261          if (s[1] == '\0' || s[2] == '\0') {
262            *p = '\0';
263            return result;
264          }
265          *p = hex_value(s[1]) * 16 + hex_value(s[2]);
266          s += 2;
267        }
268        else {
269          *p = *s;
270        }
271        p++;
272        s++;
273      }
274      *p = '\0';
275      return result;
276    }
277    
278  static const char * get_entity(char c) {  static const char * get_entity(char c) {
279    switch(c) {    switch(c) {
280    case '<':    case '<':
# Line 528  Line 566 
566    
567  static int write_json(Coverage * coverage, const char * path) {  static int write_json(Coverage * coverage, const char * path) {
568    /* write the JSON */    /* write the JSON */
569    FILE * f = fopen(path, "w");    FILE * f = fopen(path, "wb");
570    if (f == NULL) {    if (f == NULL) {
571      return -1;      return -1;
572    }    }
# Line 576  Line 614 
614      }      }
615    
616      mkdir_if_necessary(report_directory);      mkdir_if_necessary(report_directory);
617      char * path = make_path(report_directory, "jscoverage.json");      char * current_report_directory;
618        if (str_starts_with(abs_path, "/jscoverage-store/") && abs_path[18] != '\0') {
619          char * dir = decode_uri_component(abs_path + 18);
620          current_report_directory = make_path(report_directory, dir);
621          free(dir);
622        }
623        else {
624          current_report_directory = xstrdup(report_directory);
625        }
626        mkdir_if_necessary(current_report_directory);
627        char * path = make_path(current_report_directory, "jscoverage.json");
628    
629      /* check if the JSON file exists */      /* check if the JSON file exists */
630      struct stat buf;      struct stat buf;
631      if (stat(path, &buf) == 0) {      if (stat(path, &buf) == 0) {
632        /* it exists: merge */        /* it exists: merge */
633        FILE * f = fopen(path, "r");        FILE * f = fopen(path, "rb");
634        if (f == NULL) {        if (f == NULL) {
635          result = 1;          result = 1;
636        }        }
# Line 593  Line 641 
641          }          }
642        }        }
643        if (result != 0) {        if (result != 0) {
644            free(current_report_directory);
645          free(path);          free(path);
646          Coverage_delete(coverage);          Coverage_delete(coverage);
647          send_response(exchange, 500, "Could not merge with existing coverage data\n");          send_response(exchange, 500, "Could not merge with existing coverage data\n");
# Line 604  Line 653 
653      free(path);      free(path);
654      Coverage_delete(coverage);      Coverage_delete(coverage);
655      if (result != 0) {      if (result != 0) {
656          free(current_report_directory);
657        send_response(exchange, 500, "Could not write coverage data\n");        send_response(exchange, 500, "Could not write coverage data\n");
658        return;        return;
659      }      }
660    
661      /* copy other files */      /* copy other files */
662      jscoverage_copy_resources(report_directory);      jscoverage_copy_resources(current_report_directory);
663      path = make_path(report_directory, "jscoverage.js");      path = make_path(current_report_directory, "jscoverage.js");
664        free(current_report_directory);
665      FILE * f = fopen(path, "ab");      FILE * f = fopen(path, "ab");
666      free(path);      free(path);
667      if (f == NULL) {      if (f == NULL) {
# Line 668  Line 719 
719  }  }
720    
721  static void instrument_js(const char * id, const uint16_t * characters, size_t num_characters, Stream * output_stream) {  static void instrument_js(const char * id, const uint16_t * characters, size_t num_characters, Stream * output_stream) {
722      const struct Resource * resource = get_resource("report.js");
723      Stream_write(output_stream, resource->data, resource->length);
724    
725    LOCK(&javascript_mutex);    LOCK(&javascript_mutex);
726    jscoverage_instrument_js(id, characters, num_characters, output_stream);    jscoverage_instrument_js(id, characters, num_characters, output_stream);
727    UNLOCK(&javascript_mutex);    UNLOCK(&javascript_mutex);
   
   const struct Resource * resource = get_resource("report.js");  
   Stream_write(output_stream, resource->data, resource->length);  
728  }  }
729    
730  static bool is_hop_by_hop_header(const char * h) {  static bool is_hop_by_hop_header(const char * h) {
# Line 801  Line 852 
852      free(encoding);      free(encoding);
853      Stream_delete(input_stream);      Stream_delete(input_stream);
854      if (result == JSCOVERAGE_ERROR_ENCODING_NOT_SUPPORTED) {      if (result == JSCOVERAGE_ERROR_ENCODING_NOT_SUPPORTED) {
       free(characters);  
855        send_response(client_exchange, 502, "Encoding not supported\n");        send_response(client_exchange, 502, "Encoding not supported\n");
856        goto done;        goto done;
857      }      }
858      else if (result == JSCOVERAGE_ERROR_INVALID_BYTE_SEQUENCE) {      else if (result == JSCOVERAGE_ERROR_INVALID_BYTE_SEQUENCE) {
       free(characters);  
859        send_response(client_exchange, 502, "Error decoding response\n");        send_response(client_exchange, 502, "Error decoding response\n");
860        goto done;        goto done;
861      }      }
# Line 882  Line 931 
931    /* add the `Server' response-header (RFC 2616 14.38, 3.8) */    /* add the `Server' response-header (RFC 2616 14.38, 3.8) */
932    HTTPExchange_add_response_header(exchange, HTTP_SERVER, "jscoverage-server/" VERSION);    HTTPExchange_add_response_header(exchange, HTTP_SERVER, "jscoverage-server/" VERSION);
933    
934      char * decoded_path = NULL;
935    char * filesystem_path = NULL;    char * filesystem_path = NULL;
936    
937    const char * abs_path = HTTPExchange_get_abs_path(exchange);    const char * abs_path = HTTPExchange_get_abs_path(exchange);
938    assert(*abs_path != '\0');    assert(*abs_path != '\0');
939    
940    if (str_starts_with(abs_path, "/jscoverage")) {    decoded_path = decode_uri_component(abs_path);
941    
942      if (str_starts_with(decoded_path, "/jscoverage")) {
943      handle_jscoverage_request(exchange);      handle_jscoverage_request(exchange);
944      goto done;      goto done;
945    }    }
946    
947    if (strstr(abs_path, "..") != NULL) {    if (strstr(decoded_path, "..") != NULL) {
948      send_response(exchange, 403, "Forbidden\n");      send_response(exchange, 403, "Forbidden\n");
949      goto done;      goto done;
950    }    }
951    
952    filesystem_path = make_path(document_root, abs_path + 1);    filesystem_path = make_path(document_root, decoded_path + 1);
953    size_t filesystem_path_length = strlen(filesystem_path);    size_t filesystem_path_length = strlen(filesystem_path);
954    if (filesystem_path_length > 0 && filesystem_path[filesystem_path_length - 1] == '/') {    if (filesystem_path_length > 0 && filesystem_path[filesystem_path_length - 1] == '/') {
955      /* stat on Windows doesn't work with trailing slash */      /* stat on Windows doesn't work with trailing slash */
# Line 964  Line 1016 
1016        Stream_delete(input_stream);        Stream_delete(input_stream);
1017    
1018        if (result == JSCOVERAGE_ERROR_ENCODING_NOT_SUPPORTED) {        if (result == JSCOVERAGE_ERROR_ENCODING_NOT_SUPPORTED) {
         free(characters);  
1019          send_response(exchange, 500, "Encoding not supported\n");          send_response(exchange, 500, "Encoding not supported\n");
1020          goto done;          goto done;
1021        }        }
1022        else if (result == JSCOVERAGE_ERROR_INVALID_BYTE_SEQUENCE) {        else if (result == JSCOVERAGE_ERROR_INVALID_BYTE_SEQUENCE) {
         free(characters);  
1023          send_response(exchange, 500, "Error decoding JavaScript file\n");          send_response(exchange, 500, "Error decoding JavaScript file\n");
1024          goto done;          goto done;
1025        }        }
# Line 1001  Line 1051 
1051    
1052  done:  done:
1053    free(filesystem_path);    free(filesystem_path);
1054      free(decoded_path);
1055  }  }
1056    
1057  static void handler(HTTPExchange * exchange) {  static void handler(HTTPExchange * exchange) {
# Line 1041  Line 1092 
1092      else if (strcmp(argv[i], "--report-dir") == 0) {      else if (strcmp(argv[i], "--report-dir") == 0) {
1093        i++;        i++;
1094        if (i == argc) {        if (i == argc) {
1095          fatal("--report-dir: option requires an argument");          fatal_command_line("--report-dir: option requires an argument");
1096        }        }
1097        report_directory = argv[i];        report_directory = argv[i];
1098      }      }
# Line 1052  Line 1103 
1103      else if (strcmp(argv[i], "--document-root") == 0) {      else if (strcmp(argv[i], "--document-root") == 0) {
1104        i++;        i++;
1105        if (i == argc) {        if (i == argc) {
1106          fatal("--document-root: option requires an argument");          fatal_command_line("--document-root: option requires an argument");
1107        }        }
1108        document_root = argv[i];        document_root = argv[i];
1109      }      }
# Line 1063  Line 1114 
1114      else if (strcmp(argv[i], "--encoding") == 0) {      else if (strcmp(argv[i], "--encoding") == 0) {
1115        i++;        i++;
1116        if (i == argc) {        if (i == argc) {
1117          fatal("--encoding: option requires an argument");          fatal_command_line("--encoding: option requires an argument");
1118        }        }
1119        jscoverage_encoding = argv[i];        jscoverage_encoding = argv[i];
1120      }      }
# Line 1074  Line 1125 
1125      else if (strcmp(argv[i], "--ip-address") == 0) {      else if (strcmp(argv[i], "--ip-address") == 0) {
1126        i++;        i++;
1127        if (i == argc) {        if (i == argc) {
1128          fatal("--ip-address: option requires an argument");          fatal_command_line("--ip-address: option requires an argument");
1129        }        }
1130        ip_address = argv[i];        ip_address = argv[i];
1131      }      }
# Line 1089  Line 1140 
1140      else if (strcmp(argv[i], "--no-instrument") == 0) {      else if (strcmp(argv[i], "--no-instrument") == 0) {
1141        i++;        i++;
1142        if (i == argc) {        if (i == argc) {
1143          fatal("--no-instrument: option requires an argument");          fatal_command_line("--no-instrument: option requires an argument");
1144        }        }
1145        no_instrument[num_no_instrument] = argv[i];        no_instrument[num_no_instrument] = argv[i];
1146        num_no_instrument++;        num_no_instrument++;
# Line 1102  Line 1153 
1153      else if (strcmp(argv[i], "--port") == 0) {      else if (strcmp(argv[i], "--port") == 0) {
1154        i++;        i++;
1155        if (i == argc) {        if (i == argc) {
1156          fatal("--port: option requires an argument");          fatal_command_line("--port: option requires an argument");
1157        }        }
1158        port = argv[i];        port = argv[i];
1159      }      }
# Line 1119  Line 1170 
1170      }      }
1171    
1172      else if (strncmp(argv[i], "-", 1) == 0) {      else if (strncmp(argv[i], "-", 1) == 0) {
1173        fatal("unrecognized option `%s'", argv[i]);        fatal_command_line("unrecognized option `%s'", argv[i]);
1174      }      }
1175      else {      else {
1176        fatal("too many arguments");        fatal_command_line("too many arguments");
1177      }      }
1178    }    }
1179    
# Line 1130  Line 1181 
1181    char * end;    char * end;
1182    unsigned long numeric_port = strtoul(port, &end, 10);    unsigned long numeric_port = strtoul(port, &end, 10);
1183    if (*end != '\0') {    if (*end != '\0') {
1184      fatal("--port: option must be an integer");      fatal_command_line("--port: option must be an integer");
1185    }    }
1186    if (numeric_port > UINT16_MAX) {    if (numeric_port > UINT16_MAX) {
1187      fatal("--port: option must be 16 bits");      fatal_command_line("--port: option must be 16 bits");
1188    }    }
1189    
1190    /* is this a shutdown? */    /* is this a shutdown? */

Legend:
Removed from v.179  
changed lines
  Added in v.275

  ViewVC Help
Powered by ViewVC 1.1.24