【问题标题】:Parse url path of GET request解析GET请求的url路径
【发布时间】:2014-06-28 01:47:04
【问题描述】:

我是 C 新手,我已经为这个任务工作了大约 7 个小时 - 请不要说我没有尝试。

我想用C解析一个自己写的webserver的路径。假设我调用

http://localhost:8080/hello/this/is/a/test.html

然后浏览器获取

GET /hello/this/is/a/test.html HTTP/1.1

我想解析/hello/this/is/a/test.html,所以“GET”(注意GET之后的空格)和/../../..html之后的第一个空格之间的完整字符串。

到目前为止我尝试了什么:

int main() {
  ...
  char * getPathOfGetRequest(char *);
  char *pathname = getPathOfGetRequest(buf);

  printf("%s\n\n%s", buf, pathname);
  ...
}

char * getPathOfGetRequest(char *buf) {

  char *startingGet = "GET ";
  char buf_cpy[BUFLEN];
  memcpy(buf_cpy, buf, sizeof(buf));

  char *urlpath = malloc(1000);
  char *path = malloc(1000);
  urlpath = strstr(buf_cpy, startingGet);

  char delimiter[] = " ";

  path = strtok(urlpath, delimiter);
  path = strtok(NULL, delimiter);  

  return path;
}

路径名始终只有 4 个正确的字符,并且可能填充或不填充其他不相关的字符,例如 /hell32984cn)/$"§$。我猜它与strlen(startingGet)有关,但我看不出它之间的关系。我的错在哪里?

【问题讨论】:

  • 如果问题指出,具体来说,/hello/this/is/a/test.html 的解析结果是什么,也许会有所帮助?只是从字符串的开头删除'GET'?在分配的存储中返回?
  • 你说得对,谢谢。我编辑了这个问题。我需要解析 GET 之后的空白和后面的字符串结尾之间的所有内容,直到我点击下一个空白。
  • 除非你绝对需要在 XXkb 下获取程序,否则只需使用 sscanf - strtok/strsep 太可怕了。

标签: c webserver strtok


【解决方案1】:

带评论的问题代码:

char * getPathOfGetRequest(char *buf) {

  char *startingGet = "GET ";
  char buf_cpy[BUFLEN];
  memcpy(buf_cpy, buf, sizeof(buf));

上面的 memcpy 可能只会从 buf 复制 4 个字节到 buf_cpy。 这是因为 buf 是指向 char 的指针。 sizeof(buf) 是指针的大小(可能:4)。 或许,与其使用 'sizeof()',不如使用 'strlen()'。

  char *urlpath = malloc(1000);
  char *path = malloc(1000);

  urlpath = strstr(buf_cpy, startingGet);

也许提问者不清楚为什么 urlpath 被分配了 1000 字节的内存。在任何情况下,上述分配都会导致这 1000 个字节被泄露,并且违背了 'urlpath=malloc(1000)' 的目的。

以上语句的实际效果是urlpath = buf_cpy;,因为strstr()会返回'GET'在buf_copy中的开始位置。

  char delimiter[] = " ";

  path = strtok(urlpath, delimiter);

同样,上面的赋值会导致分配给 path 的 1000 字节被泄露,并且违背了上面 'path=malloc(1000)' 的目的。

  path = strtok(NULL, delimiter); 

  return path;
}

另一种编码:

char *getPathOfGetRequest(const char *buf) 
   {
   const char *start = buf;
   const char *end;
   char       *path=NULL;
   size_t      pathLen;

   /* Verify that there is a 'GET ' at the beginning of the string. */
   if(strncmp("GET ", start, 4))
      {
      fprintf(stderr, "Parse error: 'GET ' is missing.\n");
      goto CLEANUP;
      }

   /* Set the start pointer at the first character beyond the 'GET '. */
   start += 4;

   /* From the start position, set the end pointer to the first white-space character found in the string. */
   end=start;
   while(*end && !isspace(*end))
      ++end;

   /* Calculate the path length, and allocate sufficient memory for the path plus string termination. */
   pathLen = (end - start);
   path = malloc(pathLen + 1);
   if(NULL == path)
      {
      fprintf(stderr, "malloc() failed. \n");
      goto CLEANUP;
      }

   /* Copy the path string to the path storage. */
   memcpy(path, start, pathLen);

   /* Terminate the string. */
   path[pathLen] = '\0';

CLEANUP:

   /* Return the allocated storage, or NULL in the event of an error, to the caller. */
   return(path);
   }

最后,如果'strtok()'必须被使用:

char *getPathOfGetRequest(char *buf)
   {
   char *path  = NULL;

   if(strtok(buf, " "))
      {
      path = strtok(NULL, " ");
      if(path)
         path=strdup(path);
      }

   return(path);
   }

【讨论】:

  • 这就像一个魅力 - 非常感谢 Mahonri!为了您的努力和快速反应。那么,你能用几句话解释一下我做错了什么或者我可以做得更好吗?我不明白为什么我的方法不起作用。
猜你喜欢
  • 2023-02-03
  • 2021-08-22
  • 2019-07-04
  • 1970-01-01
  • 2022-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多