Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "tool_setup.h"
00023
00024 #include "strcase.h"
00025
00026 #define ENABLE_CURLX_PRINTF
00027
00028 #include "curlx.h"
00029
00030 #include "tool_cfgable.h"
00031 #include "tool_doswin.h"
00032 #include "tool_msgs.h"
00033 #include "tool_cb_hdr.h"
00034
00035 #include "memdebug.h"
00036
00037 static char *parse_filename(const char *ptr, size_t len);
00038
00039
00040
00041
00042
00043 size_t tool_header_cb(void *ptr, size_t size, size_t nmemb, void *userdata)
00044 {
00045 struct HdrCbData *hdrcbdata = userdata;
00046 struct OutStruct *outs = hdrcbdata->outs;
00047 struct OutStruct *heads = hdrcbdata->heads;
00048 const char *str = ptr;
00049 const size_t cb = size * nmemb;
00050 const char *end = (char *)ptr + cb;
00051 char *url = NULL;
00052
00053
00054
00055
00056
00057
00058
00059 size_t failure = (size * nmemb) ? 0 : 1;
00060
00061 if(!heads->config)
00062 return failure;
00063
00064 #ifdef DEBUGBUILD
00065 if(size * nmemb > (size_t)CURL_MAX_HTTP_HEADER) {
00066 warnf(heads->config->global, "Header data exceeds single call write "
00067 "limit!\n");
00068 return failure;
00069 }
00070 #endif
00071
00072
00073
00074
00075
00076 if(heads->config->headerfile && heads->stream) {
00077 size_t rc = fwrite(ptr, size, nmemb, heads->stream);
00078 if(rc != cb)
00079 return rc;
00080
00081 (void)fflush(heads->stream);
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091 if(hdrcbdata->honor_cd_filename &&
00092 (cb > 20) && checkprefix("Content-disposition:", str) &&
00093 !curl_easy_getinfo(outs->config->easy, CURLINFO_EFFECTIVE_URL, &url) &&
00094 url && (checkprefix("http://", url) || checkprefix("https://", url))) {
00095 const char *p = str + 20;
00096
00097
00098
00099 for(;;) {
00100 char *filename;
00101 size_t len;
00102
00103 while(*p && (p < end) && !ISALPHA(*p))
00104 p++;
00105 if(p > end - 9)
00106 break;
00107
00108 if(memcmp(p, "filename=", 9)) {
00109
00110 while((p < end) && (*p != ';'))
00111 p++;
00112 continue;
00113 }
00114 p += 9;
00115
00116
00117
00118
00119 len = (ssize_t)cb - (p - str);
00120 filename = parse_filename(p, len);
00121 if(filename) {
00122 outs->filename = filename;
00123 outs->alloc_filename = TRUE;
00124 outs->is_cd_filename = TRUE;
00125 outs->s_isreg = TRUE;
00126 outs->fopened = FALSE;
00127 outs->stream = NULL;
00128 hdrcbdata->honor_cd_filename = FALSE;
00129 break;
00130 }
00131 else
00132 return failure;
00133 }
00134 }
00135
00136 return cb;
00137 }
00138
00139
00140
00141
00142 static char *parse_filename(const char *ptr, size_t len)
00143 {
00144 char *copy;
00145 char *p;
00146 char *q;
00147 char stop = '\0';
00148
00149
00150 copy = malloc(len+1);
00151 if(!copy)
00152 return NULL;
00153 memcpy(copy, ptr, len);
00154 copy[len] = '\0';
00155
00156 p = copy;
00157 if(*p == '\'' || *p == '"') {
00158
00159 stop = *p;
00160 p++;
00161 }
00162 else
00163 stop = ';';
00164
00165
00166 q = strrchr(copy, '/');
00167 if(q) {
00168 p = q + 1;
00169 if(!*p) {
00170 Curl_safefree(copy);
00171 return NULL;
00172 }
00173 }
00174
00175
00176
00177
00178 q = strrchr(p, '\\');
00179 if(q) {
00180 p = q + 1;
00181 if(!*p) {
00182 Curl_safefree(copy);
00183 return NULL;
00184 }
00185 }
00186
00187
00188 for(q = p; *q; ++q) {
00189 if(*q == stop) {
00190 *q = '\0';
00191 break;
00192 }
00193 }
00194
00195
00196 q = strchr(p, '\r');
00197 if(q)
00198 *q = '\0';
00199
00200 q = strchr(p, '\n');
00201 if(q)
00202 *q = '\0';
00203
00204 if(copy != p)
00205 memmove(copy, p, strlen(p) + 1);
00206
00207 #if defined(MSDOS) || defined(WIN32)
00208 {
00209 char *sanitized;
00210 SANITIZEcode sc = sanitize_file_name(&sanitized, copy, 0);
00211 Curl_safefree(copy);
00212 if(sc)
00213 return NULL;
00214 copy = sanitized;
00215 }
00216 #endif
00217
00218
00219
00220
00221
00222 #ifdef DEBUGBUILD
00223 {
00224 char *tdir = curlx_getenv("CURL_TESTDIR");
00225 if(tdir) {
00226 char buffer[512];
00227 snprintf(buffer, sizeof(buffer), "%s/%s", tdir, copy);
00228 Curl_safefree(copy);
00229 copy = strdup(buffer);
00230
00231
00232
00233 curl_free(tdir);
00234 }
00235 }
00236 #endif
00237
00238 return copy;
00239 }
00240