诸暨麻将添加redis
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

226 lines
5.8 KiB

  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at http://curl.haxx.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. ***************************************************************************/
  22. #include "tool_setup.h"
  23. #include "rawstr.h"
  24. #define ENABLE_CURLX_PRINTF
  25. /* use our own printf() functions */
  26. #include "curlx.h"
  27. #include "tool_cfgable.h"
  28. #include "tool_msgs.h"
  29. #include "tool_cb_hdr.h"
  30. #include "memdebug.h" /* keep this as LAST include */
  31. static char *parse_filename(const char *ptr, size_t len);
  32. /*
  33. ** callback for CURLOPT_HEADERFUNCTION
  34. */
  35. size_t tool_header_cb(void *ptr, size_t size, size_t nmemb, void *userdata)
  36. {
  37. struct HdrCbData *hdrcbdata = userdata;
  38. struct OutStruct *outs = hdrcbdata->outs;
  39. struct OutStruct *heads = hdrcbdata->heads;
  40. const char *str = ptr;
  41. const size_t cb = size * nmemb;
  42. const char *end = (char*)ptr + cb;
  43. /*
  44. * Once that libcurl has called back tool_header_cb() the returned value
  45. * is checked against the amount that was intended to be written, if
  46. * it does not match then it fails with CURLE_WRITE_ERROR. So at this
  47. * point returning a value different from sz*nmemb indicates failure.
  48. */
  49. size_t failure = (size * nmemb) ? 0 : 1;
  50. if(!heads->config)
  51. return failure;
  52. #ifdef DEBUGBUILD
  53. if(size * nmemb > (size_t)CURL_MAX_HTTP_HEADER) {
  54. warnf(heads->config, "Header data exceeds single call write limit!\n");
  55. return failure;
  56. }
  57. #endif
  58. /*
  59. * Write header data when curl option --dump-header (-D) is given.
  60. */
  61. if(heads->config->headerfile && heads->stream) {
  62. size_t rc = fwrite(ptr, size, nmemb, heads->stream);
  63. if(rc != cb)
  64. return rc;
  65. }
  66. /*
  67. * This callback sets the filename where output shall be written when
  68. * curl options --remote-name (-O) and --remote-header-name (-J) have
  69. * been simultaneously given and additionally server returns an HTTP
  70. * Content-Disposition header specifying a filename property.
  71. */
  72. if(hdrcbdata->honor_cd_filename &&
  73. (cb > 20) && checkprefix("Content-disposition:", str)) {
  74. const char *p = str + 20;
  75. /* look for the 'filename=' parameter
  76. (encoded filenames (*=) are not supported) */
  77. for(;;) {
  78. char *filename;
  79. size_t len;
  80. while(*p && (p < end) && !ISALPHA(*p))
  81. p++;
  82. if(p > end - 9)
  83. break;
  84. if(memcmp(p, "filename=", 9)) {
  85. /* no match, find next parameter */
  86. while((p < end) && (*p != ';'))
  87. p++;
  88. continue;
  89. }
  90. p += 9;
  91. /* this expression below typecasts 'cb' only to avoid
  92. warning: signed and unsigned type in conditional expression
  93. */
  94. len = (ssize_t)cb - (p - str);
  95. filename = parse_filename(p, len);
  96. if(filename) {
  97. outs->filename = filename;
  98. outs->alloc_filename = TRUE;
  99. outs->is_cd_filename = TRUE;
  100. outs->s_isreg = TRUE;
  101. outs->fopened = FALSE;
  102. outs->stream = NULL;
  103. hdrcbdata->honor_cd_filename = FALSE;
  104. break;
  105. }
  106. else
  107. return failure;
  108. }
  109. }
  110. return cb;
  111. }
  112. /*
  113. * Copies a file name part and returns an ALLOCATED data buffer.
  114. */
  115. static char *parse_filename(const char *ptr, size_t len)
  116. {
  117. char *copy;
  118. char *p;
  119. char *q;
  120. char stop = '\0';
  121. /* simple implementation of strndup() */
  122. copy = malloc(len+1);
  123. if(!copy)
  124. return NULL;
  125. memcpy(copy, ptr, len);
  126. copy[len] = '\0';
  127. p = copy;
  128. if(*p == '\'' || *p == '"') {
  129. /* store the starting quote */
  130. stop = *p;
  131. p++;
  132. }
  133. else
  134. stop = ';';
  135. /* if the filename contains a path, only use filename portion */
  136. q = strrchr(copy, '/');
  137. if(q) {
  138. p = q + 1;
  139. if(!*p) {
  140. Curl_safefree(copy);
  141. return NULL;
  142. }
  143. }
  144. /* If the filename contains a backslash, only use filename portion. The idea
  145. is that even systems that don't handle backslashes as path separators
  146. probably want the path removed for convenience. */
  147. q = strrchr(p, '\\');
  148. if(q) {
  149. p = q + 1;
  150. if(!*p) {
  151. Curl_safefree(copy);
  152. return NULL;
  153. }
  154. }
  155. /* scan for the end letter and stop there */
  156. q = p;
  157. while(*q) {
  158. if(q[1] && (q[0] == '\\'))
  159. q++;
  160. else if(q[0] == stop)
  161. break;
  162. q++;
  163. }
  164. *q = '\0';
  165. /* make sure the file name doesn't end in \r or \n */
  166. q = strchr(p, '\r');
  167. if(q)
  168. *q = '\0';
  169. q = strchr(p, '\n');
  170. if(q)
  171. *q = '\0';
  172. if(copy != p)
  173. memmove(copy, p, strlen(p) + 1);
  174. /* in case we built debug enabled, we allow an evironment variable
  175. * named CURL_TESTDIR to prefix the given file name to put it into a
  176. * specific directory
  177. */
  178. #ifdef DEBUGBUILD
  179. {
  180. char *tdir = curlx_getenv("CURL_TESTDIR");
  181. if(tdir) {
  182. char buffer[512]; /* suitably large */
  183. snprintf(buffer, sizeof(buffer), "%s/%s", tdir, copy);
  184. Curl_safefree(copy);
  185. copy = strdup(buffer); /* clone the buffer, we don't use the libcurl
  186. aprintf() or similar since we want to use the
  187. same memory code as the "real" parse_filename
  188. function */
  189. curl_free(tdir);
  190. }
  191. }
  192. #endif
  193. return copy;
  194. }