Initial commit
						commit
						fa0361344c
					
				@ -0,0 +1,159 @@
 | 
				
			|||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <strings.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char * http_version_str = "HTTP/1.1 ";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct http_header {
 | 
				
			||||||
 | 
					  uint8_t * status_code_ptr;
 | 
				
			||||||
 | 
					  size_t status_code_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  size_t num_headers;
 | 
				
			||||||
 | 
					  uint8_t ** header_key_ptrs;
 | 
				
			||||||
 | 
					  size_t * header_key_lens;
 | 
				
			||||||
 | 
					  uint8_t ** header_val_ptrs;
 | 
				
			||||||
 | 
					  size_t * header_val_lens;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint8_t * body_ptr;
 | 
				
			||||||
 | 
					  size_t body_len;
 | 
				
			||||||
 | 
					} http_header_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					http_header_t * parse_header(uint8_t * data, size_t len) {
 | 
				
			||||||
 | 
					  http_header_t * ret = malloc(sizeof(http_header_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Parse version
 | 
				
			||||||
 | 
					  if(len < strlen(http_version_str)) {
 | 
				
			||||||
 | 
					    fprintf(stderr, "Data shorter than version string\n");
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  } else if(strncmp((const char *)data, http_version_str, strlen(http_version_str)) != 0) {
 | 
				
			||||||
 | 
					    fprintf(stderr, "http_version_str did not match\n");
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  size_t ptr = strlen(http_version_str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Prase status code
 | 
				
			||||||
 | 
					  size_t status_code_start = ptr;
 | 
				
			||||||
 | 
					  size_t status_code_end = 0;
 | 
				
			||||||
 | 
					  while(ptr < len-1) {
 | 
				
			||||||
 | 
					    if((data[ptr] == '\r') && (data[ptr+1] == '\n')) {
 | 
				
			||||||
 | 
					      status_code_end = ptr;
 | 
				
			||||||
 | 
					      ptr += 2;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      ptr += 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(ptr >= (len-1)) {
 | 
				
			||||||
 | 
					    fprintf(stderr, "Reached EOF while parsing status code\n");
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    ret->status_code_ptr = data + status_code_start;
 | 
				
			||||||
 | 
					    ret->status_code_len = status_code_end - status_code_start;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(ptr < len-1) {
 | 
				
			||||||
 | 
					    if((data[ptr] == '\r') && (data[ptr+1] == '\n')) {
 | 
				
			||||||
 | 
					      ret->num_headers = 0;
 | 
				
			||||||
 | 
					      return ret;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Parse header
 | 
				
			||||||
 | 
					  size_t num_headers = 0;
 | 
				
			||||||
 | 
					  uint8_t * header_key_ptrs[1024];
 | 
				
			||||||
 | 
					  uint8_t * header_val_ptrs[1024];
 | 
				
			||||||
 | 
					  size_t header_key_lens[1024];
 | 
				
			||||||
 | 
					  size_t header_val_lens[1024];
 | 
				
			||||||
 | 
					  while(ptr < len-1) {
 | 
				
			||||||
 | 
					    size_t key_start = ptr;
 | 
				
			||||||
 | 
					    size_t key_len = 0;
 | 
				
			||||||
 | 
					    while(ptr < len-1) {
 | 
				
			||||||
 | 
					      if(data[ptr] == ':') {
 | 
				
			||||||
 | 
					        key_len = ptr - key_start;
 | 
				
			||||||
 | 
					        ptr += 1;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        ptr += 1; 
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(ptr >= len-1) {
 | 
				
			||||||
 | 
					      fprintf(stderr, "Reached EOF reading header key\n");
 | 
				
			||||||
 | 
					      return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    size_t val_start = ptr;
 | 
				
			||||||
 | 
					    size_t val_len = 0;
 | 
				
			||||||
 | 
					    while(ptr < len-1) {
 | 
				
			||||||
 | 
					      if((data[ptr] == '\r') && (data[ptr+1] == '\n')) {
 | 
				
			||||||
 | 
					        val_len = ptr - val_start;
 | 
				
			||||||
 | 
					        ptr += 2;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        ptr += 1; 
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(ptr >= len-1) {
 | 
				
			||||||
 | 
					      fprintf(stderr, "Reached EOF reading header val\n");
 | 
				
			||||||
 | 
					      return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    header_key_ptrs[num_headers] = &data[key_start];
 | 
				
			||||||
 | 
					    header_key_lens[num_headers] = key_len;
 | 
				
			||||||
 | 
					    header_val_ptrs[num_headers] = &data[val_start];
 | 
				
			||||||
 | 
					    header_val_lens[num_headers] = val_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    num_headers += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(ptr < len-1) {
 | 
				
			||||||
 | 
					      if((data[ptr] == '\r') && (data[ptr+1] == '\n')) {
 | 
				
			||||||
 | 
					        ptr += 2;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ret->num_headers = num_headers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ret->header_key_ptrs = malloc(sizeof(uint8_t*)*num_headers);
 | 
				
			||||||
 | 
					  ret->header_key_lens = malloc(sizeof(size_t)*num_headers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ret->header_val_ptrs = malloc(sizeof(uint8_t*)*num_headers);
 | 
				
			||||||
 | 
					  ret->header_val_lens = malloc(sizeof(size_t)*num_headers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for(size_t i = 0; i < num_headers; i++) {
 | 
				
			||||||
 | 
					    ret->header_key_ptrs[i] = header_key_ptrs[i];
 | 
				
			||||||
 | 
					    ret->header_key_lens[i] = header_key_lens[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret->header_val_ptrs[i] = header_val_ptrs[i];
 | 
				
			||||||
 | 
					    ret->header_val_lens[i] = header_val_lens[i];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ret->body_ptr = data + ptr;
 | 
				
			||||||
 | 
					  ret->body_len = len - ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char ** argv) {
 | 
				
			||||||
 | 
					  if(argc < 2) {
 | 
				
			||||||
 | 
					    printf("Data to parse required as input\n");
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  http_header_t * header = parse_header((uint8_t*)argv[1], strlen(argv[1]));
 | 
				
			||||||
 | 
					  if(header == 0) {
 | 
				
			||||||
 | 
					    fprintf(stderr, "no header returned from parse\n");
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    printf("Parsed header with code %.*s and %d headers\n", header->status_code_len, header->status_code_ptr, header->num_headers);
 | 
				
			||||||
 | 
					    for(size_t i = 0; i < header->num_headers; i++) {
 | 
				
			||||||
 | 
					      printf("Header %ld: %.*s - %.*s\n", i,header->header_key_lens[i], header->header_key_ptrs[i], header->header_val_lens[i], header->header_val_ptrs[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue