Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add a simple debug/example utility #143

Closed
wants to merge 8 commits into from

2 participants

Corey Richardson Ben Noordhuis
Corey Richardson

No description provided.

utils/parsertrace.c
@@ -0,0 +1,79 @@
+/* Dump what the parser finds to stdout as it happen */
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "../http_parser.h"
+
+int on_message_begin(http_parser *_ __attribute__((unused))) {
Ben Noordhuis Collaborator

Preferably use (void) arg; if you want to squelch unused argument warnings. __attribute__((unused)) is a gcc extension.

Corey Richardson
cmr added a note

I had tried (void*) arg but that didn't shut gcc up.

Ben Noordhuis Collaborator

Not (void*), just (void). :-)

Corey Richardson
cmr added a note

Not sure what was going on there.. works fine here on my laptop now. It was late, what can I say :confused:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
utils/parsertrace.c
((46 lines not shown))
+ if (argc != 2) {
+ fprintf(stderr, "Usage: ./parsertrace $filename\n");
+ return EXIT_FAILURE;
+ }
+ char *filename = argv[1];
+ int fd = open(filename, O_RDONLY);
+
+ http_parser_settings settings;
+ settings.on_message_begin = on_message_begin;
+ settings.on_url = on_url;
+ settings.on_header_field = on_header_field;
+ settings.on_header_value = on_header_value;
+ settings.on_headers_complete = on_headers_complete;
+ settings.on_body = on_body;
+ settings.on_message_complete = on_message_complete;
+ http_parser *parser = malloc(sizeof(http_parser));
Ben Noordhuis Collaborator

Doesn't have to be malloc'd.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
utils/parsertrace.c
((55 lines not shown))
+ settings.on_url = on_url;
+ settings.on_header_field = on_header_field;
+ settings.on_header_value = on_header_value;
+ settings.on_headers_complete = on_headers_complete;
+ settings.on_body = on_body;
+ settings.on_message_complete = on_message_complete;
+ http_parser *parser = malloc(sizeof(http_parser));
+ http_parser_init(parser, HTTP_RESPONSE);
+
+ struct stat statinfo;
+ if(stat(argv[1], &statinfo)) {
+ fprintf(stderr, "can't stat file\n");
+ return EXIT_FAILURE;
+ }
+
+ char *data = malloc(statinfo.st_size);
Ben Noordhuis Collaborator

Free this at the end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
utils/parsertrace.c
((36 lines not shown))
+ printf("Header value: %.*s\n", (int)length, at);
+ return 0;
+}
+
+int on_body(http_parser *_ __attribute__((unused)), const char *at, size_t length) {
+ printf("Body: %.*s\n", (int)length, at);
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ if (argc != 2) {
+ fprintf(stderr, "Usage: ./parsertrace $filename\n");
+ return EXIT_FAILURE;
+ }
+ char *filename = argv[1];
+ int fd = open(filename, O_RDONLY);
Ben Noordhuis Collaborator

Use fopen/fread/fclose instead? open/read/close are only available on POSIX platforms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Corey Richardson

Thanks for the feedback. Anything else?

Corey Richardson

Hm, I'm going to add a switch for response/request/both, don't merge it in yet please.

Corey Richardson

I think it's fairly complete now.

utils/parsertrace.c
((40 lines not shown))
+ return 0;
+}
+
+int on_body(http_parser *_ , const char *at, size_t length) {
+ (void)_;
+ printf("Body: %.*s\n", (int)length, at);
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ enum http_parser_type file_type;
+ if (argc != 3) {
+err: fprintf(stderr, "Usage: %s $type $filename\n"
+ "\ttype: -x, where x is one of {r,b,q}\n"
+ "\tparses file a Response, reQuest, or Both\n"
+ , argv[0]);
Ben Noordhuis Collaborator

Put this in a function void usage(void). Backward gotos are a minor evil.

Ben Noordhuis Collaborator

And a style thing: arguments need to line up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
utils/parsertrace.c
((72 lines not shown))
+ break;
+ default:
+ goto err;
+ break;
+ }
+ }
+ char *filename = argv[2];
+ FILE *file = fopen(filename, "r");
+ if (file == NULL) {
+ fprintf(stderr, "Error: couldn't open %s\n", filename);
+ return EXIT_FAILURE;
+ }
+
+ fseek(file, 0, SEEK_END);
+ unsigned long file_length = (unsigned long)ftell(file);
+ fseek(file, 0, SEEK_SET);
Ben Noordhuis Collaborator

Indent error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
utils/parsertrace.c
((71 lines not shown))
+ file_type = HTTP_BOTH;
+ break;
+ default:
+ goto err;
+ break;
+ }
+ }
+ char *filename = argv[2];
+ FILE *file = fopen(filename, "r");
+ if (file == NULL) {
+ fprintf(stderr, "Error: couldn't open %s\n", filename);
+ return EXIT_FAILURE;
+ }
+
+ fseek(file, 0, SEEK_END);
+ unsigned long file_length = (unsigned long)ftell(file);
Ben Noordhuis Collaborator

Why the cast to unsigned? It does the wrong thing when ftell() returns -1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
utils/parsertrace.c
((75 lines not shown))
+ break;
+ }
+ }
+ char *filename = argv[2];
+ FILE *file = fopen(filename, "r");
+ if (file == NULL) {
+ fprintf(stderr, "Error: couldn't open %s\n", filename);
+ return EXIT_FAILURE;
+ }
+
+ fseek(file, 0, SEEK_END);
+ unsigned long file_length = (unsigned long)ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ char *data = malloc(file_length);
+ if(fread(data, sizeof(char), file_length, file) != file_length) {
Ben Noordhuis Collaborator

Style: space between if and paren.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
utils/parsertrace.c
@@ -0,0 +1,114 @@
+/* Dump what the parser finds to stdout as it happen */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "../http_parser.h"
Ben Noordhuis Collaborator

Can't this be #include "http_parser.h"?

Corey Richardson
cmr added a note

Sure can, after a tiny fix to the makefile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
utils/parsertrace.c
@@ -0,0 +1,114 @@
+/* Dump what the parser finds to stdout as it happen */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "../http_parser.h"
+
+int on_message_begin(http_parser *_ ) {
Ben Noordhuis Collaborator

Last style issue: http_parser uses type*, not type * (i.e. no space).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Corey Richardson cmr Style fixes
Thanks @bnoordhuis for the patience, you're awesome :)
4501d9d
Ben Noordhuis
Collaborator

Thanks Corey, landed with some touch-ups in 798eb90.

Ben Noordhuis bnoordhuis closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 12, 2012
  1. Corey Richardson
  2. Corey Richardson
Commits on Dec 13, 2012
  1. Corey Richardson

    Ignore unused arg betterly

    cmr authored
  2. Corey Richardson
  3. Corey Richardson
  4. Corey Richardson
Commits on Dec 14, 2012
  1. Corey Richardson
Commits on Dec 16, 2012
  1. Corey Richardson

    Style fixes

    cmr authored
    Thanks @bnoordhuis for the patience, you're awesome :)
This page is out of date. Refresh to see the latest.
Showing with 132 additions and 0 deletions.
  1. +2 −0  .gitignore
  2. +6 −0 Makefile
  3. +124 −0 utils/parsertrace.c
2  .gitignore
View
@@ -6,7 +6,9 @@ test
test_g
test_fast
url_parser
+parsertrace
*.mk
*.Makefile
*.so
*.a
+callgrind.out.*
6 Makefile
View
@@ -55,6 +55,12 @@ library: libhttp_parser.o
package: http_parser.o
$(AR) rcs libhttp_parser.a http_parser.o
+parsertrace_g: http_parser_g.o http_parser.h utils/parsertrace.c
+ $(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) -o parsertrace_g http_parser_g.o utils/parsertrace.c
+
+parsertrace: http_parser.o http_parser.h utils/parsertrace.c
+ $(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) -o parsertrace http_parser.o utils/parsertrace.c
+
tags: http_parser.c http_parser.h test.c
ctags $^
124 utils/parsertrace.c
View
@@ -0,0 +1,124 @@
+/* Dump what the parser finds to stdout as it happen */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "http_parser.h"
+
+int on_message_begin(http_parser* _ ) {
+ (void)_;
+ printf("\n***MESSAGE BEGIN***\n\n");
+ return 0;
+}
+
+int on_headers_complete(http_parser* _ ) {
+ (void)_;
+ printf("\n***HEADERS COMPLETE***\n\n");
+ return 0;
+}
+
+int on_message_complete(http_parser* _ ) {
+ (void)_;
+ printf("\n***MESSAGE COMPLETE***\n\n");
+ return 0;
+}
+
+int on_url(http_parser* _ , const char* at, size_t length) {
+ (void)_;
+ printf("Url: %.*s\n", (int)length, at);
+ return 0;
+}
+
+int on_header_field(http_parser* _ , const char* at, size_t length) {
+ (void)_;
+ printf("Header field: %.*s\n", (int)length, at);
+ return 0;
+}
+
+int on_header_value(http_parser* _ , const char* at, size_t length) {
+ (void)_;
+ printf("Header value: %.*s\n", (int)length, at);
+ return 0;
+}
+
+int on_body(http_parser* _ , const char* at, size_t length) {
+ (void)_;
+ printf("Body: %.*s\n", (int)length, at);
+ return 0;
+}
+
+void usage(const char* name) {
+ fprintf(stderr, "Usage: %s $type $filename\n"
+ "\ttype: -x, where x is one of {r,b,q}\n"
+ "\tparses file as a Response, reQuest, or Both\n"
+ , name);
+}
+int main(int argc, char* argv[]) {
+ enum http_parser_type file_type;
+ if (argc != 3) {
+ return EXIT_FAILURE;
+ }
+ char* type = argv[1];
+ if (type[0] != '-') {
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ } else {
+ switch(type[1]) {
+ /* in the case of "-", type[1] will be NUL */
+ case 'r':
+ file_type = HTTP_RESPONSE;
+ break;
+ case 'q':
+ file_type = HTTP_REQUEST;
+ break;
+ case 'b':
+ file_type = HTTP_BOTH;
+ break;
+ default:
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ break;
+ }
+ }
+ char* filename = argv[2];
+ FILE* file = fopen(filename, "r");
+ if (file == NULL) {
+ fprintf(stderr, "Error: couldn't open %s\n", filename);
+ return EXIT_FAILURE;
+ }
+
+ fseek(file, 0, SEEK_END);
+
+ long file_length = ftell(file);
+ if (file_length == -1) {
+ fprintf(stderr, "Error: ftell failed");
+ return EXIT_FAILURE;
+ }
+
+ fseek(file, 0, SEEK_SET);
+
+ char* data = malloc(file_length);
+ if (fread(data, sizeof(char), (size_t)file_length, file) != (size_t)file_length) {
+ fprintf(stderr, "couldn't read entire file (please report this as a bug!)\n");
+ return EXIT_FAILURE;
+ }
+
+ http_parser_settings settings;
+ settings.on_message_begin = on_message_begin;
+ settings.on_url = on_url;
+ settings.on_header_field = on_header_field;
+ settings.on_header_value = on_header_value;
+ settings.on_headers_complete = on_headers_complete;
+ settings.on_body = on_body;
+ settings.on_message_complete = on_message_complete;
+ http_parser parser;
+ http_parser_init(&parser, file_type);
+
+ if (http_parser_execute(&parser, &settings, data, file_length) != (size_t)file_length) {
+ fprintf(stderr, "Error: %s (%s)\n",
+ http_errno_description(HTTP_PARSER_ERRNO(&parser)),
+ http_errno_name(HTTP_PARSER_ERRNO(&parser)));
+ }
+
+ free(data);
+ return EXIT_SUCCESS;
+}
Something went wrong with that request. Please try again.