aboutsummaryrefslogtreecommitdiff
path: root/networking/wget.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/wget.c')
-rw-r--r--networking/wget.c98
1 files changed, 78 insertions, 20 deletions
diff --git a/networking/wget.c b/networking/wget.c
index 1013f66cb..6c8bd90a8 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -38,8 +38,14 @@
38 38
39#if 0 39#if 0
40# define log_io(...) bb_error_msg(__VA_ARGS__) 40# define log_io(...) bb_error_msg(__VA_ARGS__)
41# define SENDFMT(fp, fmt, ...) \
42 do { \
43 log_io("> " fmt, ##__VA_ARGS__); \
44 fprintf(fp, fmt, ##__VA_ARGS__); \
45 } while (0);
41#else 46#else
42# define log_io(...) ((void)0) 47# define log_io(...) ((void)0)
48# define SENDFMT(fp, fmt, ...) fprintf(fp, fmt, ##__VA_ARGS__)
43#endif 49#endif
44 50
45 51
@@ -55,6 +61,36 @@ static const char P_FTP[] = "ftp";
55static const char P_HTTP[] = "http"; 61static const char P_HTTP[] = "http";
56static const char P_HTTPS[] = "https"; 62static const char P_HTTPS[] = "https";
57 63
64#if ENABLE_FEATURE_WGET_LONG_OPTIONS
65/* User-specified headers prevent using our corresponding built-in headers. */
66enum {
67 HDR_HOST = (1<<0),
68 HDR_USER_AGENT = (1<<1),
69 HDR_RANGE = (1<<2),
70 HDR_AUTH = (1<<3) * ENABLE_FEATURE_WGET_AUTHENTICATION,
71 HDR_PROXY_AUTH = (1<<4) * ENABLE_FEATURE_WGET_AUTHENTICATION,
72};
73static const char wget_user_headers[] ALIGN1 =
74 "Host:\0"
75 "User-Agent:\0"
76 "Range:\0"
77# if ENABLE_FEATURE_WGET_AUTHENTICATION
78 "Authorization:\0"
79 "Proxy-Authorization:\0"
80# endif
81 ;
82# define USR_HEADER_HOST (G.user_headers & HDR_HOST)
83# define USR_HEADER_USER_AGENT (G.user_headers & HDR_USER_AGENT)
84# define USR_HEADER_RANGE (G.user_headers & HDR_RANGE)
85# define USR_HEADER_AUTH (G.user_headers & HDR_AUTH)
86# define USR_HEADER_PROXY_AUTH (G.user_headers & HDR_PROXY_AUTH)
87#else /* No long options, no user-headers :( */
88# define USR_HEADER_HOST 0
89# define USR_HEADER_USER_AGENT 0
90# define USR_HEADER_RANGE 0
91# define USR_HEADER_AUTH 0
92# define USR_HEADER_PROXY_AUTH 0
93#endif
58 94
59/* Globals */ 95/* Globals */
60struct globals { 96struct globals {
@@ -69,6 +105,7 @@ struct globals {
69#if ENABLE_FEATURE_WGET_LONG_OPTIONS 105#if ENABLE_FEATURE_WGET_LONG_OPTIONS
70 char *post_data; 106 char *post_data;
71 char *extra_headers; 107 char *extra_headers;
108 unsigned char user_headers; /* Headers mentioned by the user */
72#endif 109#endif
73 char *fname_out; /* where to direct output (-O) */ 110 char *fname_out; /* where to direct output (-O) */
74 const char *proxy_flag; /* Use proxies if env vars are set */ 111 const char *proxy_flag; /* Use proxies if env vars are set */
@@ -830,43 +867,46 @@ static void download_one_url(const char *url)
830#endif 867#endif
831 /* Send HTTP request */ 868 /* Send HTTP request */
832 if (use_proxy) { 869 if (use_proxy) {
833 fprintf(sfp, "GET %s://%s/%s HTTP/1.1\r\n", 870 SENDFMT(sfp, "GET %s://%s/%s HTTP/1.1\r\n",
834 target.protocol, target.host, 871 target.protocol, target.host,
835 target.path); 872 target.path);
836 } else { 873 } else {
837 fprintf(sfp, "%s /%s HTTP/1.1\r\n", 874 SENDFMT(sfp, "%s /%s HTTP/1.1\r\n",
838 (option_mask32 & WGET_OPT_POST_DATA) ? "POST" : "GET", 875 (option_mask32 & WGET_OPT_POST_DATA) ? "POST" : "GET",
839 target.path); 876 target.path);
840 } 877 }
841 878 if (!USR_HEADER_HOST)
842 fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n", 879 SENDFMT(sfp, "Host: %s\r\n", target.host);
843 target.host, G.user_agent); 880 if (!USR_HEADER_USER_AGENT)
881 SENDFMT(sfp, "User-Agent: %s\r\n", G.user_agent);
844 882
845 /* Ask server to close the connection as soon as we are done 883 /* Ask server to close the connection as soon as we are done
846 * (IOW: we do not intend to send more requests) 884 * (IOW: we do not intend to send more requests)
847 */ 885 */
848 fprintf(sfp, "Connection: close\r\n"); 886 SENDFMT(sfp, "Connection: close\r\n");
849 887
850#if ENABLE_FEATURE_WGET_AUTHENTICATION 888#if ENABLE_FEATURE_WGET_AUTHENTICATION
851 if (target.user) { 889 if (target.user && !USR_HEADER_AUTH) {
852 fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6, 890 SENDFMT(sfp, "Proxy-Authorization: Basic %s\r\n"+6,
853 base64enc(target.user)); 891 base64enc(target.user));
854 } 892 }
855 if (use_proxy && server.user) { 893 if (use_proxy && server.user && !USR_HEADER_PROXY_AUTH) {
856 fprintf(sfp, "Proxy-Authorization: Basic %s\r\n", 894 SENDFMT(sfp, "Proxy-Authorization: Basic %s\r\n",
857 base64enc(server.user)); 895 base64enc(server.user));
858 } 896 }
859#endif 897#endif
860 898
861 if (G.beg_range != 0) 899 if (G.beg_range != 0 && !USR_HEADER_RANGE)
862 fprintf(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range); 900 SENDFMT(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range);
863 901
864#if ENABLE_FEATURE_WGET_LONG_OPTIONS 902#if ENABLE_FEATURE_WGET_LONG_OPTIONS
865 if (G.extra_headers) 903 if (G.extra_headers) {
904 log_io(G.extra_headers);
866 fputs(G.extra_headers, sfp); 905 fputs(G.extra_headers, sfp);
906 }
867 907
868 if (option_mask32 & WGET_OPT_POST_DATA) { 908 if (option_mask32 & WGET_OPT_POST_DATA) {
869 fprintf(sfp, 909 SENDFMT(sfp,
870 "Content-Type: application/x-www-form-urlencoded\r\n" 910 "Content-Type: application/x-www-form-urlencoded\r\n"
871 "Content-Length: %u\r\n" 911 "Content-Length: %u\r\n"
872 "\r\n" 912 "\r\n"
@@ -876,7 +916,7 @@ static void download_one_url(const char *url)
876 } else 916 } else
877#endif 917#endif
878 { 918 {
879 fprintf(sfp, "\r\n"); 919 SENDFMT(sfp, "\r\n");
880 } 920 }
881 921
882 fflush(sfp); 922 fflush(sfp);
@@ -1093,7 +1133,9 @@ int wget_main(int argc UNUSED_PARAM, char **argv)
1093#if ENABLE_FEATURE_WGET_LONG_OPTIONS 1133#if ENABLE_FEATURE_WGET_LONG_OPTIONS
1094 applet_long_options = wget_longopts; 1134 applet_long_options = wget_longopts;
1095#endif 1135#endif
1096 opt_complementary = "-1" IF_FEATURE_WGET_TIMEOUT(":T+") IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::"); 1136 opt_complementary = "-1"
1137 IF_FEATURE_WGET_TIMEOUT(":T+")
1138 IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::");
1097 getopt32(argv, "csqO:P:Y:U:T:" /*ignored:*/ "t:", 1139 getopt32(argv, "csqO:P:Y:U:T:" /*ignored:*/ "t:",
1098 &G.fname_out, &G.dir_prefix, 1140 &G.fname_out, &G.dir_prefix,
1099 &G.proxy_flag, &G.user_agent, 1141 &G.proxy_flag, &G.user_agent,
@@ -1106,16 +1148,32 @@ int wget_main(int argc UNUSED_PARAM, char **argv)
1106 1148
1107#if ENABLE_FEATURE_WGET_LONG_OPTIONS 1149#if ENABLE_FEATURE_WGET_LONG_OPTIONS
1108 if (headers_llist) { 1150 if (headers_llist) {
1109 int size = 1; 1151 int size = 0;
1110 char *cp; 1152 char *hdr;
1111 llist_t *ll = headers_llist; 1153 llist_t *ll = headers_llist;
1112 while (ll) { 1154 while (ll) {
1113 size += strlen(ll->data) + 2; 1155 size += strlen(ll->data) + 2;
1114 ll = ll->link; 1156 ll = ll->link;
1115 } 1157 }
1116 G.extra_headers = cp = xmalloc(size); 1158 G.extra_headers = hdr = xmalloc(size + 1);
1117 while (headers_llist) { 1159 while (headers_llist) {
1118 cp += sprintf(cp, "%s\r\n", (char*)llist_pop(&headers_llist)); 1160 int bit;
1161 const char *words;
1162
1163 size = sprintf(hdr, "%s\r\n",
1164 (char*)llist_pop(&headers_llist));
1165 /* a bit like index_in_substrings but don't match full key */
1166 bit = 1;
1167 words = wget_user_headers;
1168 while (*words) {
1169 if (strstr(hdr, words) == hdr) {
1170 G.user_headers |= bit;
1171 break;
1172 }
1173 bit <<= 1;
1174 words += strlen(words) + 1;
1175 }
1176 hdr += size;
1119 } 1177 }
1120 } 1178 }
1121#endif 1179#endif