Esempio n. 1
0
int file_write_http_header(FILE *data_file, const char *filename, int file_size, u16_t *http_hdr_len,
                           u16_t *http_hdr_chksum, u8_t provide_content_len, int is_compressed)
{
  int i = 0;
  int response_type = HTTP_HDR_OK;
  const char* file_type;
  const char *cur_string;
  size_t cur_len;
  int written = 0;
  size_t hdr_len = 0;
  u16_t acc;
  const char *file_ext;
  int j;
  u8_t provide_last_modified = includeLastModified;

  memset(hdr_buf, 0, sizeof(hdr_buf));
  
  if (useHttp11) {
    response_type = HTTP_HDR_OK_11;
  }

  fprintf(data_file, NEWLINE "/* HTTP header */");
  if (strstr(filename, "404") == filename) {
    response_type = HTTP_HDR_NOT_FOUND;
    if (useHttp11) {
      response_type = HTTP_HDR_NOT_FOUND_11;
    }
  } else if (strstr(filename, "400") == filename) {
    response_type = HTTP_HDR_BAD_REQUEST;
    if (useHttp11) {
      response_type = HTTP_HDR_BAD_REQUEST_11;
    }
  } else if (strstr(filename, "501") == filename) {
    response_type = HTTP_HDR_NOT_IMPL;
    if (useHttp11) {
      response_type = HTTP_HDR_NOT_IMPL_11;
    }
  }
  cur_string = g_psHTTPHeaderStrings[response_type];
  cur_len = strlen(cur_string);
  fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
  written += file_put_ascii(data_file, cur_string, cur_len, &i);
  i = 0;
  if (precalcChksum) {
    memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
    hdr_len += cur_len;
  }

  cur_string = serverID;
  cur_len = strlen(cur_string);
  fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
  written += file_put_ascii(data_file, cur_string, cur_len, &i);
  i = 0;
  if (precalcChksum) {
    memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
    hdr_len += cur_len;
  }

  file_ext = filename;
  if (file_ext != NULL) {
    while(strstr(file_ext, ".") != NULL) {
      file_ext = strstr(file_ext, ".");
      file_ext++;
    }
  }
  if ((file_ext == NULL) || (*file_ext == 0)) {
    printf("failed to get extension for file \"%s\", using default.\n", filename);
    file_type = HTTP_HDR_DEFAULT_TYPE;
  } else {
    file_type = NULL;
    for (j = 0; j < NUM_HTTP_HEADERS; j++) {
      if (!strcmp(file_ext, g_psHTTPHeaders[j].extension)) {
        file_type = g_psHTTPHeaders[j].content_type;
        break;
      }
    }
    if (file_type == NULL) {
      printf("failed to get file type for extension \"%s\", using default.\n", file_ext);
      file_type = HTTP_HDR_DEFAULT_TYPE;
    }
  }

  /* Content-Length is used for persistent connections in HTTP/1.1 but also for
     download progress in older versions
     @todo: just use a big-enough buffer and let the HTTPD send spaces? */
  if (provide_content_len) {
    char intbuf[MAX_PATH_LEN];
    int content_len = file_size;
    memset(intbuf, 0, sizeof(intbuf));
    cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH];
    cur_len = strlen(cur_string);
    fprintf(data_file, NEWLINE "/* \"%s%d\r\n\" (%d+ bytes) */" NEWLINE, cur_string, content_len, cur_len+2);
    written += file_put_ascii(data_file, cur_string, cur_len, &i);
    if (precalcChksum) {
      memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
      hdr_len += cur_len;
    }

    _itoa(content_len, intbuf, 10);
    strcat(intbuf, "\r\n");
    cur_len = strlen(intbuf);
    written += file_put_ascii(data_file, intbuf, cur_len, &i);
    i = 0;
    if (precalcChksum) {
      memcpy(&hdr_buf[hdr_len], intbuf, cur_len);
      hdr_len += cur_len;
    }
  }
  if (provide_last_modified) {
    char modbuf[256];
    struct stat stat_data;
    struct tm* t;
    memset(modbuf, 0, sizeof(modbuf));
    memset(&stat_data, 0, sizeof(stat_data));
    cur_string = modbuf;
    strcpy(modbuf, "Last-Modified: ");
    if (stat(filename, &stat_data) != 0) {
       printf("stat(%s) failed with error %d\n", filename, errno);
       exit(-1);
    }
    t = gmtime(&stat_data.st_mtime);
    if (t == NULL) {
       printf("gmtime() failed with error %d\n", errno);
       exit(-1);
    }
    strftime(&modbuf[15], sizeof(modbuf)-15, "%a, %d %b %Y %H:%M:%S GMT", t);
    cur_len = strlen(cur_string);
    fprintf(data_file, NEWLINE "/* \"%s\"\r\n\" (%d+ bytes) */" NEWLINE, cur_string, cur_len+2);
    written += file_put_ascii(data_file, cur_string, cur_len, &i);
    if (precalcChksum) {
      memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
      hdr_len += cur_len;
    }

    modbuf[0] = 0;
    strcat(modbuf, "\r\n");
    cur_len = strlen(modbuf);
    written += file_put_ascii(data_file, modbuf, cur_len, &i);
    i = 0;
    if (precalcChksum) {
      memcpy(&hdr_buf[hdr_len], modbuf, cur_len);
      hdr_len += cur_len;
    }
  }

  /* HTTP/1.1 implements persistent connections */
  if (useHttp11) {
    if (provide_content_len) {
      cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_KEEPALIVE];
    } else {
      /* no Content-Length available, so a persistent connection is no possible
         because the client does not know the data length */
      cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_CLOSE];
    }
    cur_len = strlen(cur_string);
    fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
    written += file_put_ascii(data_file, cur_string, cur_len, &i);
    i = 0;
    if (precalcChksum) {
      memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
      hdr_len += cur_len;
    }
  }

#if MAKEFS_SUPPORT_DEFLATE
  if (is_compressed) {
    /* tell the client about the deflate encoding */
    LWIP_ASSERT("error", deflateNonSsiFiles);
    cur_string = "Content-Encoding: deflate\r\n";
    cur_len = strlen(cur_string);
    fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
    written += file_put_ascii(data_file, cur_string, cur_len, &i);
    i = 0;
  }
#else
  LWIP_UNUSED_ARG(is_compressed);
#endif

  /* write content-type, ATTENTION: this includes the double-CRLF! */
  cur_string = file_type;
  cur_len = strlen(cur_string);
  fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
  written += file_put_ascii(data_file, cur_string, cur_len, &i);
  i = 0;

  /* ATTENTION: headers are done now (double-CRLF has been written!) */

  if (precalcChksum) {
    memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
    hdr_len += cur_len;

    LWIP_ASSERT("hdr_len <= 0xffff", hdr_len <= 0xffff);
    LWIP_ASSERT("strlen(hdr_buf) == hdr_len", strlen(hdr_buf) == hdr_len);
    acc = ~inet_chksum(hdr_buf, (u16_t)hdr_len);
    *http_hdr_len = (u16_t)hdr_len;
    *http_hdr_chksum = acc;
  }

  return written;
}
Esempio n. 2
0
int file_write_http_header(FILE *data_file, const char *filename, int file_size,
                           u16_t *http_hdr_len, u16_t *http_hdr_chksum)
{
  int i = 0;
  int response_type = HTTP_HDR_OK;
  int file_type = HTTP_HDR_DEFAULT_TYPE;
  const char *cur_string;
  size_t cur_len;
  int written = 0;
  size_t hdr_len = 0;
  u16_t acc;
  const char *file_ext;
  int j;

  memset(hdr_buf, 0, sizeof(hdr_buf));
  
  if (useHttp11) {
    response_type = HTTP_HDR_OK_11;
  }

  fprintf(data_file, NEWLINE "/* HTTP header */");
  if (strstr(filename, "404") == filename) {
    response_type = HTTP_HDR_NOT_FOUND;
    if (useHttp11) {
      response_type = HTTP_HDR_NOT_FOUND_11;
    }
  } else if (strstr(filename, "400") == filename) {
    response_type = HTTP_HDR_BAD_REQUEST;
    if (useHttp11) {
      response_type = HTTP_HDR_BAD_REQUEST_11;
    }
  } else if (strstr(filename, "501") == filename) {
    response_type = HTTP_HDR_NOT_IMPL;
    if (useHttp11) {
      response_type = HTTP_HDR_NOT_IMPL_11;
    }
  }
  cur_string = g_psHTTPHeaderStrings[response_type];
  cur_len = strlen(cur_string);
  fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
  written += file_put_ascii(data_file, cur_string, cur_len, &i);
  i = 0;
  if (precalcChksum) {
    memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
    hdr_len += cur_len;
  }

  cur_string = serverID;
  cur_len = strlen(cur_string);
  fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
  written += file_put_ascii(data_file, cur_string, cur_len, &i);
  i = 0;
  if (precalcChksum) {
    memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
    hdr_len += cur_len;
  }

  file_ext = filename;
  while(strstr(file_ext, ".") != NULL) {
    file_ext = strstr(file_ext, ".");
    file_ext++;
  }
  if((file_ext == NULL) || (*file_ext == 0)) {
    printf("failed to get extension for file \"%s\", using default.\n", filename);
  } else {
    for(j = 0; j < NUM_HTTP_HEADERS; j++) {
      if(!strcmp(file_ext, g_psHTTPHeaders[j].extension)) {
        file_type = g_psHTTPHeaders[j].headerIndex;
        break;
      }
    }
    if (j >= NUM_HTTP_HEADERS) {
      printf("failed to get file type for extension \"%s\", using default.\n", file_ext);
      file_type = HTTP_HDR_DEFAULT_TYPE;
    }
  }

  if (useHttp11) {
    char intbuf[MAX_PATH_LEN];
    memset(intbuf, 0, sizeof(intbuf));

    cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH];
    cur_len = strlen(cur_string);
    fprintf(data_file, NEWLINE "/* \"%s%d\r\n\" (%d+ bytes) */" NEWLINE, cur_string, file_size, cur_len+2);
    written += file_put_ascii(data_file, cur_string, cur_len, &i);
    if (precalcChksum) {
      memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
      hdr_len += cur_len;
    }

    _itoa(file_size, intbuf, 10);
    strcat(intbuf, "\r\n");
    cur_len = strlen(intbuf);
    written += file_put_ascii(data_file, intbuf, cur_len, &i);
    i = 0;
    if (precalcChksum) {
      memcpy(&hdr_buf[hdr_len], intbuf, cur_len);
      hdr_len += cur_len;
    }

    cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_CLOSE];
    cur_len = strlen(cur_string);
    fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
    written += file_put_ascii(data_file, cur_string, cur_len, &i);
    i = 0;
    if (precalcChksum) {
      memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
      hdr_len += cur_len;
    }
  }

  cur_string = g_psHTTPHeaderStrings[file_type];
  cur_len = strlen(cur_string);
  fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
  written += file_put_ascii(data_file, cur_string, cur_len, &i);
  i = 0;
  if (precalcChksum) {
    memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
    hdr_len += cur_len;

    LWIP_ASSERT("hdr_len <= 0xffff", hdr_len <= 0xffff);
    LWIP_ASSERT("strlen(hdr_buf) == hdr_len", strlen(hdr_buf) == hdr_len);
    acc = ~inet_chksum(hdr_buf, (u16_t)hdr_len);
    *http_hdr_len = (u16_t)hdr_len;
    *http_hdr_chksum = acc;
  }

  return written;
}
Esempio n. 3
0
int process_file(FILE *data_file, FILE *struct_file, const char *filename)
{
  char varname[MAX_PATH_LEN];
  int i = 0;
  char qualifiedName[MAX_PATH_LEN];
  int file_size;
  u16_t http_hdr_chksum = 0;
  u16_t http_hdr_len = 0;
  int chksum_count = 0;
  u8_t flags = 0;
  const char* flags_str;
  u8_t has_content_len;
  u8_t* file_data;
  int is_compressed = 0;

  /* create qualified name (@todo: prepend slash or not?) */
  sprintf(qualifiedName,"%s/%s", curSubdir, filename);
  /* create C variable name */
  strcpy(varname, qualifiedName);
  /* convert slashes & dots to underscores */
  fix_filename_for_c(varname, MAX_PATH_LEN);
  register_filename(varname);
#if ALIGN_PAYLOAD
  /* to force even alignment of array, type 1 */
  fprintf(data_file, "#if FSDATA_FILE_ALIGNMENT==1" NEWLINE);
  fprintf(data_file, "static const " PAYLOAD_ALIGN_TYPE " dummy_align_%s = %d;" NEWLINE, varname, payload_alingment_dummy_counter++);
  fprintf(data_file, "#endif" NEWLINE);
#endif /* ALIGN_PAYLOAD */
  fprintf(data_file, "static const unsigned char FSDATA_ALIGN_PRE data_%s[] FSDATA_ALIGN_POST = {" NEWLINE, varname);
  /* encode source file name (used by file system, not returned to browser) */
  fprintf(data_file, "/* %s (%d chars) */" NEWLINE, qualifiedName, strlen(qualifiedName)+1);
  file_put_ascii(data_file, qualifiedName, strlen(qualifiedName)+1, &i);
#if ALIGN_PAYLOAD
  /* pad to even number of bytes to assure payload is on aligned boundary */
  while(i % PAYLOAD_ALIGNMENT != 0) {
    fprintf(data_file, "0x%02.2x,", 0);
    i++;
  }
#endif /* ALIGN_PAYLOAD */
  fprintf(data_file, NEWLINE);

  has_content_len = !is_ssi_file(filename);
  file_data = get_file_data(filename, &file_size, includeHttpHeader && has_content_len, &is_compressed);
  if (includeHttpHeader) {
    file_write_http_header(data_file, filename, file_size, &http_hdr_len, &http_hdr_chksum, has_content_len, is_compressed);
    flags = FS_FILE_FLAGS_HEADER_INCLUDED;
    if (has_content_len) {
      flags |= FS_FILE_FLAGS_HEADER_PERSISTENT;
    }
  }
  if (precalcChksum) {
    chksum_count = write_checksums(struct_file, varname, http_hdr_len, http_hdr_chksum, file_data, file_size);
  }

  /* build declaration of struct fsdata_file in temp file */
  fprintf(struct_file, "const struct fsdata_file file_%s[] = { {" NEWLINE, varname);
  fprintf(struct_file, "file_%s," NEWLINE, lastFileVar);
  fprintf(struct_file, "data_%s," NEWLINE, varname);
  fprintf(struct_file, "data_%s + %d," NEWLINE, varname, i);
  fprintf(struct_file, "sizeof(data_%s) - %d," NEWLINE, varname, i);
  switch(flags)
  {
  case(FS_FILE_FLAGS_HEADER_INCLUDED):
     flags_str = "FS_FILE_FLAGS_HEADER_INCLUDED";
     break;
  case(FS_FILE_FLAGS_HEADER_PERSISTENT):
     flags_str = "FS_FILE_FLAGS_HEADER_PERSISTENT";
     break;
  case(FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT):
     flags_str = "FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT";
     break;
  default:
     flags_str = "0";
     break;
  }
  fprintf(struct_file, "%s," NEWLINE, flags_str);
  if (precalcChksum) {
    fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE);
    fprintf(struct_file, "%d, chksums_%s," NEWLINE, chksum_count, varname);
    fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE);
  }
  fprintf(struct_file, "}};" NEWLINE NEWLINE);
  strcpy(lastFileVar, varname);

  /* write actual file contents */
  i = 0;
  fprintf(data_file, NEWLINE "/* raw file data (%d bytes) */" NEWLINE, file_size);
  process_file_data(data_file, file_data, file_size);
  fprintf(data_file, "};" NEWLINE NEWLINE);
  free(file_data);
  return 0;
}
Esempio n. 4
0
int process_file(FILE *data_file, FILE *struct_file, const char *filename)
{
  char *pch;
  char varname[MAX_PATH_LEN];
  int i = 0;
  char qualifiedName[MAX_PATH_LEN];
  int file_size;
  u16_t http_hdr_chksum = 0;
  u16_t http_hdr_len = 0;
  int chksum_count = 0;

  /* create qualified name (TODO: prepend slash or not?) */
  sprintf(qualifiedName,"%s/%s", curSubdir, filename);
  /* create C variable name */
  strcpy(varname, qualifiedName);
  /* convert slashes & dots to underscores */
  while ((pch = strpbrk(varname, "./\\")) != NULL) {
    *pch = '_';
  }
#if ALIGN_PAYLOAD
  /* to force even alignment of array */
  fprintf(data_file, "static const " PAYLOAD_ALIGN_TYPE " dummy_align_%s = %d;" NEWLINE, varname, payload_alingment_dummy_counter++);
#endif /* ALIGN_PAYLOAD */
  fprintf(data_file, "static const unsigned char data_%s[] = {" NEWLINE, varname);
  /* encode source file name (used by file system, not returned to browser) */
  fprintf(data_file, "/* %s (%d chars) */" NEWLINE, qualifiedName, strlen(qualifiedName)+1);
  file_put_ascii(data_file, qualifiedName, strlen(qualifiedName)+1, &i);
#if ALIGN_PAYLOAD
  /* pad to even number of bytes to assure payload is on aligned boundary */
  while(i % PAYLOAD_ALIGNMENT != 0) {
    fprintf(data_file, "0x%02.2x,", 0);
    i++;
  }
#endif /* ALIGN_PAYLOAD */
  fprintf(data_file, NEWLINE);

  file_size = get_file_size(filename);
  if (includeHttpHeader) {
    file_write_http_header(data_file, filename, file_size, &http_hdr_len, &http_hdr_chksum);
  }
  if (precalcChksum) {
    chksum_count = write_checksums(struct_file, filename, varname, http_hdr_len, http_hdr_chksum);
  }

  /* build declaration of struct fsdata_file in temp file */
  fprintf(struct_file, "const struct fsdata_file file_%s[] = { {" NEWLINE, varname);
  fprintf(struct_file, "file_%s," NEWLINE, lastFileVar);
  fprintf(struct_file, "data_%s," NEWLINE, varname);
  fprintf(struct_file, "data_%s + %d," NEWLINE, varname, i);
  fprintf(struct_file, "sizeof(data_%s) - %d," NEWLINE, varname, i);
  fprintf(struct_file, "%d," NEWLINE, includeHttpHeader);
  if (precalcChksum) {
    fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE);
    fprintf(struct_file, "%d, chksums_%s," NEWLINE, chksum_count, varname);
    fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE);
  }
  fprintf(struct_file, "}};" NEWLINE NEWLINE);
  strcpy(lastFileVar, varname);

  /* write actual file contents */
  i = 0;
  fprintf(data_file, NEWLINE "/* raw file data (%d bytes) */" NEWLINE, file_size);
  process_file_data(filename, data_file);
  fprintf(data_file, "};" NEWLINE NEWLINE);

  return 0;
}