http.c (97859) | http.c (97866) |
---|---|
1/*- 2 * Copyright (c) 2000 Dag-Erling Co�dan Sm�rgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 13 unchanged lines hidden (view full) --- 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2000 Dag-Erling Co�dan Sm�rgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 13 unchanged lines hidden (view full) --- 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/lib/libfetch/http.c 97859 2002-06-05 10:31:01Z des $"); | 30__FBSDID("$FreeBSD: head/lib/libfetch/http.c 97866 2002-06-05 12:19:08Z des $"); |
31 32/* 33 * The following copyright applies to the base64 code: 34 * 35 *- 36 * Copyright 1997 Massachusetts Institute of Technology 37 * 38 * Permission to use, copy, modify, and distribute this software and --- 63 unchanged lines hidden (view full) --- 102 103/***************************************************************************** 104 * I/O functions for decoding chunked streams 105 */ 106 107struct httpio 108{ 109 conn_t *conn; /* connection */ | 31 32/* 33 * The following copyright applies to the base64 code: 34 * 35 *- 36 * Copyright 1997 Massachusetts Institute of Technology 37 * 38 * Permission to use, copy, modify, and distribute this software and --- 63 unchanged lines hidden (view full) --- 102 103/***************************************************************************** 104 * I/O functions for decoding chunked streams 105 */ 106 107struct httpio 108{ 109 conn_t *conn; /* connection */ |
110 int chunked; /* chunked mode */ |
|
110 char *buf; /* chunk buffer */ | 111 char *buf; /* chunk buffer */ |
111 size_t b_size; /* size of chunk buffer */ 112 ssize_t b_len; /* amount of data currently in buffer */ 113 int b_pos; /* current read offset in buffer */ | 112 size_t bufsize; /* size of chunk buffer */ 113 ssize_t buflen; /* amount of data currently in buffer */ 114 int bufpos; /* current read offset in buffer */ |
114 int eof; /* end-of-file flag */ 115 int error; /* error flag */ 116 size_t chunksize; /* remaining size of current chunk */ 117#ifndef NDEBUG 118 size_t total; 119#endif 120}; 121 --- 37 unchanged lines hidden (view full) --- 159 (unsigned long)io->chunksize, (unsigned long)io->total); 160 } 161#endif 162 163 return (io->chunksize); 164} 165 166/* | 115 int eof; /* end-of-file flag */ 116 int error; /* error flag */ 117 size_t chunksize; /* remaining size of current chunk */ 118#ifndef NDEBUG 119 size_t total; 120#endif 121}; 122 --- 37 unchanged lines hidden (view full) --- 160 (unsigned long)io->chunksize, (unsigned long)io->total); 161 } 162#endif 163 164 return (io->chunksize); 165} 166 167/* |
168 * Grow the input buffer to at least len bytes 169 */ 170static inline int 171_http_growbuf(struct httpio *io, size_t len) 172{ 173 char *tmp; 174 175 if (io->bufsize >= len) 176 return (0); 177 178 if ((tmp = realloc(io->buf, len)) == NULL) 179 return (-1); 180 io->buf = tmp; 181 io->bufsize = len; 182} 183 184/* |
|
167 * Fill the input buffer, do chunk decoding on the fly 168 */ 169static int | 185 * Fill the input buffer, do chunk decoding on the fly 186 */ 187static int |
170_http_fillbuf(struct httpio *io) | 188_http_fillbuf(struct httpio *io, size_t len) |
171{ 172 if (io->error) 173 return (-1); 174 if (io->eof) 175 return (0); 176 | 189{ 190 if (io->error) 191 return (-1); 192 if (io->eof) 193 return (0); 194 |
195 if (io->chunked == 0) { 196 if (_http_growbuf(io, len) == -1) 197 return (-1); 198 if ((io->buflen = _fetch_read(io->conn, io->buf, len)) == -1) 199 return (-1); 200 io->bufpos = 0; 201 return (io->buflen); 202 } 203 |
|
177 if (io->chunksize == 0) { 178 switch (_http_new_chunk(io)) { 179 case -1: 180 io->error = 1; 181 return (-1); 182 case 0: 183 io->eof = 1; 184 return (0); 185 } 186 } 187 | 204 if (io->chunksize == 0) { 205 switch (_http_new_chunk(io)) { 206 case -1: 207 io->error = 1; 208 return (-1); 209 case 0: 210 io->eof = 1; 211 return (0); 212 } 213 } 214 |
188 if (io->b_size < io->chunksize) { 189 char *tmp; 190 191 if ((tmp = realloc(io->buf, io->chunksize)) == NULL) 192 return (-1); 193 io->buf = tmp; 194 io->b_size = io->chunksize; 195 } 196 197 if ((io->b_len = read(io->conn->sd, io->buf, io->chunksize)) == -1) | 215 if (len > io->chunksize) 216 len = io->chunksize; 217 if (_http_growbuf(io, len) == -1) |
198 return (-1); | 218 return (-1); |
199 io->chunksize -= io->b_len; | 219 if ((io->buflen = _fetch_read(io->conn, io->buf, len)) == -1) 220 return (-1); 221 io->chunksize -= io->buflen; |
200 201 if (io->chunksize == 0) { 202 char endl[2]; 203 | 222 223 if (io->chunksize == 0) { 224 char endl[2]; 225 |
204 if (read(io->conn->sd, &endl[0], 1) == -1 || 205 read(io->conn->sd, &endl[1], 1) == -1 || | 226 if (_fetch_read(io->conn, endl, 2) != 2 || |
206 endl[0] != '\r' || endl[1] != '\n') 207 return (-1); 208 } 209 | 227 endl[0] != '\r' || endl[1] != '\n') 228 return (-1); 229 } 230 |
210 io->b_pos = 0; | 231 io->bufpos = 0; |
211 | 232 |
212 return (io->b_len); | 233 return (io->buflen); |
213} 214 215/* 216 * Read function 217 */ 218static int 219_http_readfn(void *v, char *buf, int len) 220{ 221 struct httpio *io = (struct httpio *)v; 222 int l, pos; 223 224 if (io->error) 225 return (-1); 226 if (io->eof) 227 return (0); 228 229 for (pos = 0; len > 0; pos += l, len -= l) { 230 /* empty buffer */ | 234} 235 236/* 237 * Read function 238 */ 239static int 240_http_readfn(void *v, char *buf, int len) 241{ 242 struct httpio *io = (struct httpio *)v; 243 int l, pos; 244 245 if (io->error) 246 return (-1); 247 if (io->eof) 248 return (0); 249 250 for (pos = 0; len > 0; pos += l, len -= l) { 251 /* empty buffer */ |
231 if (!io->buf || io->b_pos == io->b_len) 232 if (_http_fillbuf(io) < 1) | 252 if (!io->buf || io->bufpos == io->buflen) 253 if (_http_fillbuf(io, len) < 1) |
233 break; | 254 break; |
234 l = io->b_len - io->b_pos; | 255 l = io->buflen - io->bufpos; |
235 if (len < l) 236 l = len; | 256 if (len < l) 257 l = len; |
237 bcopy(io->buf + io->b_pos, buf + pos, l); 238 io->b_pos += l; | 258 bcopy(io->buf + io->bufpos, buf + pos, l); 259 io->bufpos += l; |
239 } 240 241 if (!pos && io->error) 242 return (-1); 243 return (pos); 244} 245 246/* 247 * Write function 248 */ 249static int 250_http_writefn(void *v, const char *buf, int len) 251{ 252 struct httpio *io = (struct httpio *)v; 253 | 260 } 261 262 if (!pos && io->error) 263 return (-1); 264 return (pos); 265} 266 267/* 268 * Write function 269 */ 270static int 271_http_writefn(void *v, const char *buf, int len) 272{ 273 struct httpio *io = (struct httpio *)v; 274 |
254 return (write(io->conn->sd, buf, len)); | 275 return (_fetch_write(io->conn, buf, len)); |
255} 256 257/* 258 * Close function 259 */ 260static int 261_http_closefn(void *v) 262{ --- 6 unchanged lines hidden (view full) --- 269 free(io); 270 return (r); 271} 272 273/* 274 * Wrap a file descriptor up 275 */ 276static FILE * | 276} 277 278/* 279 * Close function 280 */ 281static int 282_http_closefn(void *v) 283{ --- 6 unchanged lines hidden (view full) --- 290 free(io); 291 return (r); 292} 293 294/* 295 * Wrap a file descriptor up 296 */ 297static FILE * |
277_http_funopen(conn_t *conn) | 298_http_funopen(conn_t *conn, int chunked) |
278{ 279 struct httpio *io; 280 FILE *f; 281 282 if ((io = calloc(1, sizeof *io)) == NULL) { 283 _fetch_syserr(); 284 return (NULL); 285 } 286 io->conn = conn; | 299{ 300 struct httpio *io; 301 FILE *f; 302 303 if ((io = calloc(1, sizeof *io)) == NULL) { 304 _fetch_syserr(); 305 return (NULL); 306 } 307 io->conn = conn; |
308 io->chunked = chunked; |
|
287 f = funopen(io, _http_readfn, _http_writefn, NULL, _http_closefn); 288 if (f == NULL) { 289 _fetch_syserr(); 290 free(io); 291 return (NULL); 292 } 293 return (f); 294} --- 425 unchanged lines hidden (view full) --- 720 721 722/***************************************************************************** 723 * Core 724 */ 725 726/* 727 * Send a request and process the reply | 309 f = funopen(io, _http_readfn, _http_writefn, NULL, _http_closefn); 310 if (f == NULL) { 311 _fetch_syserr(); 312 free(io); 313 return (NULL); 314 } 315 return (f); 316} --- 425 unchanged lines hidden (view full) --- 742 743 744/***************************************************************************** 745 * Core 746 */ 747 748/* 749 * Send a request and process the reply |
750 * 751 * XXX This function is way too long, the do..while loop should be split 752 * XXX off into a separate function. |
|
728 */ 729FILE * 730_http_request(struct url *URL, const char *op, struct url_stat *us, 731 struct url *purl, const char *flags) 732{ 733 conn_t *conn; 734 struct url *url, *new; 735 int chunked, direct, need_auth, noredirect, verbose; --- 279 unchanged lines hidden (view full) --- 1015 goto ouch; 1016 } 1017 1018 /* report back real offset and size */ 1019 URL->offset = offset; 1020 URL->length = clength; 1021 1022 /* wrap it up in a FILE */ | 753 */ 754FILE * 755_http_request(struct url *URL, const char *op, struct url_stat *us, 756 struct url *purl, const char *flags) 757{ 758 conn_t *conn; 759 struct url *url, *new; 760 int chunked, direct, need_auth, noredirect, verbose; --- 279 unchanged lines hidden (view full) --- 1040 goto ouch; 1041 } 1042 1043 /* report back real offset and size */ 1044 URL->offset = offset; 1045 URL->length = clength; 1046 1047 /* wrap it up in a FILE */ |
1023 if (chunked) { 1024 f = _http_funopen(conn); 1025 } else { 1026 f = fdopen(dup(conn->sd), "r"); 1027 _fetch_close(conn); 1028 } 1029 if (f == NULL) { | 1048 if ((f = _http_funopen(conn, chunked)) == NULL) { |
1030 _fetch_syserr(); 1031 goto ouch; 1032 } 1033 1034 if (url != URL) 1035 fetchFreeURL(url); 1036 if (purl) 1037 fetchFreeURL(purl); --- 75 unchanged lines hidden --- | 1049 _fetch_syserr(); 1050 goto ouch; 1051 } 1052 1053 if (url != URL) 1054 fetchFreeURL(url); 1055 if (purl) 1056 fetchFreeURL(purl); --- 75 unchanged lines hidden --- |