Fix a few minor nits.
[opusfile.git] / src / http.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7  *                                                                  *
8  * THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2012                *
9  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
10  *                                                                  *
11  ********************************************************************/
12 #include "internal.h"
13 #include <ctype.h>
14 #include <errno.h>
15 #include <limits.h>
16 #include <string.h>
17
18 /*RFCs referenced in this file:
19   RFC  761: DOD Standard Transmission Control Protocol
20   RFC 1738: Uniform Resource Locators (URL)
21   RFC 1945: Hypertext Transfer Protocol -- HTTP/1.0
22   RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1
23   RFC 2145: Use and Interpretation of HTTP Version Numbers
24   RFC 2246: The TLS Protocol Version 1.0
25   RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1
26   RFC 2617: HTTP Authentication: Basic and Digest Access Authentication
27   RFC 2817: Upgrading to TLS Within HTTP/1.1
28   RFC 2818: HTTP Over TLS
29   RFC 3492: Punycode: A Bootstring encoding of Unicode for Internationalized
30    Domain Names in Applications (IDNA)
31   RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
32   RFC 3987: Internationalized Resource Identifiers (IRIs)
33   RFC 5894: Internationalized Domain Names for Applications (IDNA):
34    Background, Explanation, and Rationale
35   RFC 6066: Transport Layer Security (TLS) Extensions: Extension Definitions*/
36
37 typedef struct OpusParsedURL   OpusParsedURL;
38 typedef struct OpusStringBuf   OpusStringBuf;
39 typedef struct OpusHTTPConn    OpusHTTPConn;
40 typedef struct OpusHTTPStream  OpusHTTPStream;
41
42 static char *op_string_range_dup(const char *_start,const char *_end){
43   size_t  len;
44   char   *ret;
45   OP_ASSERT(_start<=_end);
46   len=_end-_start;
47   ret=(char *)_ogg_malloc(sizeof(*ret)*(len+1));
48   if(OP_LIKELY(ret!=NULL)){
49     memcpy(ret,_start,sizeof(*ret)*(len));
50     ret[len]='\0';
51   }
52   return ret;
53 }
54
55 static char *op_string_dup(const char *_s){
56   return op_string_range_dup(_s,_s+strlen(_s));
57 }
58
59 static char *op_string_tolower(char *_s){
60   int i;
61   for(i=0;_s[i]!='\0';i++){
62     int c;
63     c=_s[i];
64     if(c>='A'&&c<='Z')c+='a'-'A';
65     _s[i]=(char)c;
66   }
67   return _s;
68 }
69
70 /*URI character classes (from RFC 3986).*/
71 #define OP_URL_ALPHA \
72  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
73 #define OP_URL_DIGIT       "0123456789"
74 #define OP_URL_HEXDIGIT    "0123456789ABCDEFabcdef"
75 /*Not a character class, but the characters allowed in <scheme>.*/
76 #define OP_URL_SCHEME      OP_URL_ALPHA OP_URL_DIGIT "+-."
77 #define OP_URL_GEN_DELIMS  "#/:?@[]"
78 #define OP_URL_SUB_DELIMS  "!$&'()*+,;="
79 #define OP_URL_RESERVED    OP_URL_GEN_DELIMS OP_URL_SUB_DELIMS
80 #define OP_URL_UNRESERVED  OP_URL_ALPHA OP_URL_DIGIT "-._~"
81 /*Not a character class, but the characters allowed in <pct-encoded>.*/
82 #define OP_URL_PCT_ENCODED "%"
83 /*Not a character class or production rule, but for convenience.*/
84 #define OP_URL_PCHAR_BASE \
85  OP_URL_UNRESERVED OP_URL_PCT_ENCODED OP_URL_SUB_DELIMS
86 #define OP_URL_PCHAR       OP_URL_PCHAR_BASE ":@"
87 /*Not a character class, but the characters allowed in <userinfo> and
88    <IP-literal>.*/
89 #define OP_URL_PCHAR_NA    OP_URL_PCHAR_BASE ":"
90 /*Not a character class, but the characters allowed in <segment-nz-nc>.*/
91 #define OP_URL_PCHAR_NC    OP_URL_PCHAR_BASE "@"
92 /*Not a character clsss, but the characters allowed in <path>.*/
93 #define OP_URL_PATH        OP_URL_PCHAR "/"
94 /*Not a character class, but the characters allowed in <query> / <fragment>.*/
95 #define OP_URL_QUERY_FRAG  OP_URL_PCHAR "/?"
96
97 /*Check the <% HEXDIG HEXDIG> escapes of a URL for validity.
98   Return: 0 if valid, or a negative value on failure.*/
99 static int op_validate_url_escapes(const char *_s){
100   int i;
101   for(i=0;_s[i];i++){
102     if(_s[i]=='%'){
103       if(OP_UNLIKELY(!isxdigit(_s[i+1]))
104        ||OP_UNLIKELY(!isxdigit(_s[i+2]))
105        /*RFC 3986 says %00 "should be rejected if the application is not
106           expecting to receive raw data within a component."*/
107        ||OP_UNLIKELY(_s[i+1]=='0'&&_s[i+2]=='0')){
108         return OP_FALSE;
109       }
110       i+=2;
111     }
112   }
113   return 0;
114 }
115
116 /*Convert a hex digit to its actual value.
117   _c: The hex digit to convert.
118       Presumed to be valid ('0'...'9', 'A'...'F', or 'a'...'f').
119   Return: The value of the digit, in the range [0,15].*/
120 static int op_hex_value(int _c){
121   return _c>='a'?_c-'a'+10:_c>='A'?_c-'A'+10:_c-'0';
122 }
123
124 /*Unescape all the <% HEXDIG HEXDIG> sequences in a string in-place.
125   This does no validity checking.*/
126 static char *op_unescape_url_component(char *_s){
127   int i;
128   int j;
129   for(i=j=0;_s[i];i++,j++){
130     if(_s[i]=='%'){
131       _s[i]=(char)(op_hex_value(_s[i+1])<<4|op_hex_value(_s[i+2]));
132       i+=2;
133     }
134   }
135   return _s;
136 }
137
138 /*Parse a file: URL.
139   This code is not meant to be fast: strspn() with large sets is likely to be
140    slow, but it is very convenient.
141   It is meant to be RFC 1738-compliant (as updated by RFC 3986).*/
142 static const char *op_parse_file_url(const char *_src){
143   const char *scheme_end;
144   const char *path;
145   const char *path_end;
146   scheme_end=_src+strspn(_src,OP_URL_SCHEME);
147   if(OP_UNLIKELY(*scheme_end!=':')
148    ||scheme_end-_src!=4||op_strncasecmp(_src,"file",4)!=0){
149     /*Unsupported protocol.*/
150     return NULL;
151   }
152   /*Make sure all escape sequences are valid to simplify unescaping later.*/
153   if(OP_UNLIKELY(op_validate_url_escapes(scheme_end+1)<0))return NULL;
154   if(scheme_end[1]=='/'&&scheme_end[2]=='/'){
155     const char *host;
156     /*file: URLs can have a host!
157       Yeah, I was surprised, too, but that's what RFC 1738 says.
158       It also says, "The file URL scheme is unusual in that it does not specify
159        an Internet protocol or access method for such files; as such, its
160        utility in network protocols between hosts is limited," which is a mild
161        understatement.*/
162     host=scheme_end+3;
163     /*The empty host is what we expect.*/
164     if(OP_LIKELY(*host=='/'))path=host;
165     else{
166       const char *host_end;
167       char        host_buf[28];
168       /*RFC 1738 says localhost "is interpreted as `the machine from which the
169          URL is being interpreted,'" so let's check for it.*/
170       host_end=host+strspn(host,OP_URL_PCHAR_BASE);
171       /*No <port> allowed.
172         This also rejects IP-Literals.*/
173       if(*host_end!='/')return NULL;
174       /*An escaped "localhost" can take at most 27 characters.*/
175       if(OP_UNLIKELY(host_end-host>27))return NULL;
176       memcpy(host_buf,host,sizeof(*host_buf)*(host_end-host));
177       host_buf[host_end-host]='\0';
178       op_unescape_url_component(host_buf);
179       op_string_tolower(host_buf);
180       /*Some other host: give up.*/
181       if(OP_UNLIKELY(strcmp(host_buf,"localhost")!=0))return NULL;
182       path=host_end;
183     }
184   }
185   else path=scheme_end+1;
186   path_end=path+strspn(path,OP_URL_PATH);
187   /*This will reject a <query> or <fragment> component, too.
188     I don't know what to do with queries, but a temporal fragment would at
189      least make sense.
190     RFC 1738 pretty clearly defines a <searchpart> that's equivalent to the
191      RFC 3986 <query> component for other schemes, but not the file: scheme,
192      so I'm going to just reject it.*/
193   if(*path_end!='\0')return NULL;
194   return path;
195 }
196
197 #if defined(OP_ENABLE_HTTP)
198 # include <sys/ioctl.h>
199 # include <sys/types.h>
200 # include <sys/socket.h>
201 # include <sys/timeb.h>
202 # include <arpa/inet.h>
203 # include <netinet/in.h>
204 # include <netinet/tcp.h>
205 # include <fcntl.h>
206 # include <netdb.h>
207 # include <poll.h>
208 # include <unistd.h>
209 # include <openssl/ssl.h>
210
211 /*The maximum number of simultaneous connections.
212   RFC 2616 says this SHOULD NOT be more than 2, but everyone on the modern web
213    ignores that (e.g., IE 8 bumped theirs up from 2 to 6, Firefox uses 15).
214   If it makes you feel better, we'll only ever actively read from one of these
215    at a time.
216   The others are kept around mainly to avoid slow-starting a new connection
217    when seeking, and time out rapidly.*/
218 # define OP_NCONNS_MAX (4)
219
220 /*The number of redirections at which we give up.
221   The value here is the current default in Firefox.
222   RFC 2068 mandated a maximum of 5, but RFC 2616 relaxed that to "a client
223    SHOULD detect infinite redirection loops."
224   Fortunately, 20 is less than infinity.*/
225 # define OP_REDIRECT_LIMIT (20)
226
227 /*The initial size of the buffer used to read a response message (before the
228    body).*/
229 # define OP_RESPONSE_SIZE_MIN (510)
230 /*The maximum size of a response message (before the body).
231   Responses larger than this will be discarded.
232   I've seen a real server return 20 kB of data for a 302 Found response.
233   Increasing this beyond 32kB will cause problems on platforms with a 16-bit
234    int.*/
235 # define OP_RESPONSE_SIZE_MAX (32766)
236
237 /*The number of milliseconds we will allow a connection to sit idle before we
238    refuse to resurrect it.
239   Apache as of 2.2 has reduced its default timeout to 5 seconds (from 15), so
240    that's what we'll use here.*/
241 # define OP_CONNECTION_IDLE_TIMEOUT_MS (5*1000)
242
243 /*The number of milliseconds we will wait to send or receive data before giving
244    up.*/
245 # define OP_POLL_TIMEOUT_MS (30*1000)
246
247 /*We will always attempt to read ahead at least this much in preference to
248    opening a new connection.*/
249 # define OP_READAHEAD_THRESH_MIN (32*(opus_int32)1024)
250 /*The amount to read ahead per iteration of the read-ahead loop.
251   16 kB is the largest size OpenSSL will return at once.*/
252 # define OP_READAHEAD_CHUNK_SIZE (16*1024)
253
254 /*The amount of data to request after a seek.
255   This is a trade-off between read throughput after a seek vs. the the ability
256    to quickly perform another seek with the same connection.*/
257 # define OP_PIPELINE_CHUNK_SIZE     (32*(opus_int32)1024)
258 /*Subsequent chunks are requested with larger and larger sizes until they pass
259    this threshold, after which we just ask for the rest of the resource.*/
260 # define OP_PIPELINE_CHUNK_SIZE_MAX (1024*(opus_int32)1024)
261 /*This is the maximum number of requests we'll make with a single connection.
262   Many servers will simply disconnect after we attempt some number of requests,
263    possibly without sending a Connection: close header, meaning we won't
264    discover it until we try to read beyond the end of the current chunk.
265   We can reconnect when that happens, but this is slow.
266   Instead, we impose a limit ourselves (set to the default for Apache
267    installations and thus likely the most common value in use).*/
268 # define OP_PIPELINE_MAX_REQUESTS   (100)
269 /*This should be the number of requests, starting from a chunk size of
270    OP_PIPELINE_CHUNK_SIZE and doubling each time, until we exceed
271    OP_PIPELINE_CHUNK_SIZE_MAX and just request the rest of the file.
272   We won't reuse a connection when seeking unless it has at least this many
273    requests left, to reduce the chances we'll have to open a new connection
274    while reading forward afterwards.*/
275 # define OP_PIPELINE_MIN_REQUESTS   (7)
276
277 /*Is this an https URL?
278   For now we can simply check the last letter of the scheme.*/
279 # define OP_URL_IS_SSL(_url) ((_url)->scheme[4]=='s')
280
281 /*Does this URL use the default port for its scheme?*/
282 # define OP_URL_IS_DEFAULT_PORT(_url) \
283  (!OP_URL_IS_SSL(_url)&&(_url)->port==80 \
284  ||OP_URL_IS_SSL(_url)&&(_url)->port==443)
285
286 struct OpusParsedURL{
287   /*Either "http" or "https".*/
288   char     *scheme;
289   /*The user name from the <userinfo> component, or NULL.*/
290   char     *user;
291   /*The password from the <userinfo> component, or NULL.*/
292   char     *pass;
293   /*The <host> component.
294     This may not be NULL.*/
295   char     *host;
296   /*The <path> and <query> components.
297     This may not be NULL.*/
298   char     *path;
299   /*The <port> component.
300     This is set to the default port if the URL did not contain one.*/
301   unsigned  port;
302 };
303
304 /*Parse a URL.
305   This code is not meant to be fast: strspn() with large sets is likely to be
306    slow, but it is very convenient.
307   It is meant to be RFC 3986-compliant.
308   We currently do not support IRIs (Internationalized Resource Identifiers,
309    RFC 3987).
310   Callers should translate them to URIs first.*/
311 static int op_parse_url_impl(OpusParsedURL *_dst,const char *_src){
312   const char  *scheme_end;
313   const char  *authority;
314   const char  *userinfo_end;
315   const char  *user;
316   const char  *user_end;
317   const char  *pass;
318   const char  *hostport;
319   const char  *hostport_end;
320   const char  *host_end;
321   const char  *port;
322   opus_int32   port_num;
323   const char  *port_end;
324   const char  *path;
325   const char  *path_end;
326   const char  *uri_end;
327   scheme_end=_src+strspn(_src,OP_URL_SCHEME);
328   if(OP_UNLIKELY(*scheme_end!=':')
329    ||OP_UNLIKELY(scheme_end-_src<4)||OP_UNLIKELY(scheme_end-_src>5)
330    ||OP_UNLIKELY(op_strncasecmp(_src,"https",scheme_end-_src)!=0)){
331     /*Unsupported protocol.*/
332     return OP_EIMPL;
333   }
334   if(OP_UNLIKELY(scheme_end[1]!='/')||OP_UNLIKELY(scheme_end[2]!='/')){
335     /*We require an <authority> component.*/
336     return OP_EINVAL;
337   }
338   authority=scheme_end+3;
339   /*Make sure all escape sequences are valid to simplify unescaping later.*/
340   if(OP_UNLIKELY(op_validate_url_escapes(authority)<0))return OP_EINVAL;
341   /*Look for a <userinfo> component.*/
342   userinfo_end=authority+strspn(authority,OP_URL_PCHAR_NA);
343   if(*userinfo_end=='@'){
344     /*Found one.*/
345     user=authority;
346     /*Look for a password (yes, clear-text passwords are deprecated, I know,
347        but what else are people supposed to use? use SSL if you care).*/
348     user_end=authority+strspn(authority,OP_URL_PCHAR_BASE);
349     if(*user_end==':')pass=user_end+1;
350     else pass=NULL;
351     hostport=userinfo_end+1;
352   }
353   else{
354     /*We shouldn't have to initialize user_end, but gcc is too dumb to figure
355        out that user!=NULL below means we didn't take this else branch.*/
356     user=user_end=NULL;
357     pass=NULL;
358     hostport=authority;
359   }
360   /*Try to figure out where the <host> component ends.*/
361   if(hostport[0]=='['){
362     hostport++;
363     /*We have an <IP-literal>, which can contain colons.*/
364     hostport_end=host_end=hostport+strspn(hostport,OP_URL_PCHAR_NA);
365     if(OP_UNLIKELY(*hostport_end++!=']'))return OP_EINVAL;
366   }
367   /*Currently we don't support IDNA (RFC 5894), because I don't want to deal
368      with the policy about which domains should not be internationalized to
369      avoid confusing similarities.
370     Give this API Punycode (RFC 3492) domain names instead.*/
371   else hostport_end=host_end=hostport+strspn(hostport,OP_URL_PCHAR_BASE);
372   /*TODO: Validate host.*/
373   /*Is there a port number?*/
374   port_num=-1;
375   if(*hostport_end==':'){
376     int i;
377     port=hostport_end+1;
378     port_end=port+strspn(port,OP_URL_DIGIT);
379     path=port_end;
380     /*Not part of RFC 3986, but require port numbers in the range 0...65535.*/
381     if(OP_LIKELY(port_end-port>0)){
382       while(*port=='0')port++;
383       if(OP_UNLIKELY(port_end-port>5))return OP_EINVAL;
384       port_num=0;
385       for(i=0;i<port_end-port;i++)port_num=port_num*10+port[i]-'0';
386       if(OP_UNLIKELY(port_num>65535))return OP_EINVAL;
387     }
388   }
389   else path=hostport_end;
390   path_end=path+strspn(path,OP_URL_PATH);
391   /*If the path is not empty, it must begin with a '/'.*/
392   if(OP_LIKELY(path_end>path)&&OP_UNLIKELY(path[0]!='/'))return OP_EINVAL;
393   /*Consume the <query> component, if any (right now we don't split this out
394      from the <path> component).*/
395   if(*path_end=='?')path_end=path_end+strspn(path_end,OP_URL_QUERY_FRAG);
396   /*Discard the <fragment> component, if any.
397     This doesn't get sent to the server.
398     Some day we should add support for Media Fragment URIs
399      <http://www.w3.org/TR/media-frags/>.*/
400   if(*path_end=='#')uri_end=path_end+1+strspn(path_end+1,OP_URL_QUERY_FRAG);
401   else uri_end=path_end;
402   /*If there's anything left, this was not a valid URL.*/
403   if(OP_UNLIKELY(*uri_end!='\0'))return OP_EINVAL;
404   _dst->scheme=op_string_range_dup(_src,scheme_end);
405   if(OP_UNLIKELY(_dst->scheme==NULL))return OP_EFAULT;
406   op_string_tolower(_dst->scheme);
407   if(user!=NULL){
408     _dst->user=op_string_range_dup(user,user_end);
409     if(OP_UNLIKELY(_dst->user==NULL))return OP_EFAULT;
410     op_unescape_url_component(_dst->user);
411     /*Unescaping might have created a ':' in the username.
412       That's not allowed by RFC 2617's Basic Authentication Scheme.*/
413     if(OP_UNLIKELY(strchr(_dst->user,':')!=NULL))return OP_EINVAL;
414   }
415   else _dst->user=NULL;
416   if(pass!=NULL){
417     _dst->pass=op_string_range_dup(pass,userinfo_end);
418     if(OP_UNLIKELY(_dst->pass==NULL))return OP_EFAULT;
419     op_unescape_url_component(_dst->pass);
420   }
421   else _dst->pass=NULL;
422   _dst->host=op_string_range_dup(hostport,host_end);
423   if(OP_UNLIKELY(_dst->host==NULL))return OP_EFAULT;
424   if(port_num<0){
425     if(_src[4]=='s')port_num=443;
426     else port_num=80;
427   }
428   _dst->port=(unsigned)port_num;
429   /*RFC 2616 says an empty <abs-path> component is equivalent to "/", and we
430      MUST use the latter in the Request-URI.
431     Reserve space for the slash here.*/
432   if(path==path_end||path[0]=='?')path--;
433   _dst->path=op_string_range_dup(path,path_end);
434   if(OP_UNLIKELY(_dst->path==NULL))return OP_EFAULT;
435   /*And force-set it here.*/
436   _dst->path[0]='/';
437   return 0;
438 }
439
440 static void op_parsed_url_init(OpusParsedURL *_url){
441   memset(_url,0,sizeof(*_url));
442 }
443
444 static void op_parsed_url_clear(OpusParsedURL *_url){
445   _ogg_free(_url->scheme);
446   _ogg_free(_url->user);
447   _ogg_free(_url->pass);
448   _ogg_free(_url->host);
449   _ogg_free(_url->path);
450 }
451
452 static int op_parse_url(OpusParsedURL *_dst,const char *_src){
453   OpusParsedURL url;
454   int           ret;
455   op_parsed_url_init(&url);
456   ret=op_parse_url_impl(&url,_src);
457   if(OP_UNLIKELY(ret<0))op_parsed_url_clear(&url);
458   else *_dst=*&url;
459   return ret;
460 }
461
462 /*A buffer to hold growing strings.
463   The main purpose of this is to consolidate allocation checks and simplify
464    cleanup on a failed allocation.*/
465 struct OpusStringBuf{
466   char *buf;
467   int   nbuf;
468   int   cbuf;
469 };
470
471 static void op_sb_init(OpusStringBuf *_sb){
472   _sb->buf=NULL;
473   _sb->nbuf=0;
474   _sb->cbuf=0;
475 }
476
477 static void op_sb_clear(OpusStringBuf *_sb){
478   _ogg_free(_sb->buf);
479 }
480
481 static int op_sb_ensure_capacity(OpusStringBuf *_sb,int _capacity){
482   char *buf;
483   int   cbuf;
484   buf=_sb->buf;
485   cbuf=_sb->cbuf;
486   if(_capacity>=cbuf-1){
487     if(OP_UNLIKELY(cbuf>INT_MAX-1>>1))return OP_EFAULT;
488     if(OP_UNLIKELY(_capacity>=INT_MAX-1))return OP_EFAULT;
489     cbuf=OP_MAX(2*cbuf+1,_capacity+1);
490     buf=_ogg_realloc(buf,sizeof(*buf)*cbuf);
491     if(OP_UNLIKELY(buf==NULL))return OP_EFAULT;
492     _sb->buf=buf;
493     _sb->cbuf=cbuf;
494   }
495   return 0;
496 }
497
498 static int op_sb_grow(OpusStringBuf *_sb,int _max_size){
499   char *buf;
500   int   cbuf;
501   buf=_sb->buf;
502   cbuf=_sb->cbuf;
503   OP_ASSERT(_max_size<=INT_MAX-1);
504   cbuf=cbuf<=_max_size-1>>1?2*cbuf+1:_max_size+1;
505   buf=_ogg_realloc(buf,sizeof(*buf)*cbuf);
506   if(OP_UNLIKELY(buf==NULL))return OP_EFAULT;
507   _sb->buf=buf;
508   _sb->cbuf=cbuf;
509   return 0;
510 }
511
512 static int op_sb_append(OpusStringBuf *_sb,const char *_s,int _len){
513   char *buf;
514   int   nbuf;
515   int   ret;
516   nbuf=_sb->nbuf;
517   if(OP_UNLIKELY(nbuf>INT_MAX-_len))return OP_EFAULT;
518   ret=op_sb_ensure_capacity(_sb,nbuf+_len);
519   if(OP_UNLIKELY(ret<0))return ret;
520   buf=_sb->buf;
521   memcpy(buf+nbuf,_s,sizeof(*buf)*_len);
522   nbuf+=_len;
523   buf[nbuf]='\0';
524   _sb->nbuf=nbuf;
525   return 0;
526 }
527
528 static int op_sb_append_string(OpusStringBuf *_sb,const char *_s){
529   return op_sb_append(_sb,_s,strlen(_s));
530 }
531
532 static int op_sb_append_port(OpusStringBuf *_sb,unsigned _port){
533   char port_buf[7];
534   OP_ASSERT(_port<=65535U);
535   sprintf(port_buf,":%u",_port);
536   return op_sb_append_string(_sb,port_buf);
537 }
538
539 static int op_sb_append_nonnegative_int64(OpusStringBuf *_sb,opus_int64 _i){
540   char digit;
541   int  nbuf_start;
542   int  ret;
543   OP_ASSERT(_i>=0);
544   nbuf_start=_sb->nbuf;
545   ret=0;
546   do{
547     digit='0'+_i%10;
548     ret|=op_sb_append(_sb,&digit,1);
549     _i/=10;
550   }
551   while(_i>0);
552   if(OP_LIKELY(ret>=0)){
553     char *buf;
554     int   nbuf_end;
555     buf=_sb->buf;
556     nbuf_end=_sb->nbuf-1;
557     /*We've added the digits backwards.
558       Reverse them.*/
559     while(nbuf_start<nbuf_end){
560       digit=buf[nbuf_start];
561       buf[nbuf_start]=buf[nbuf_end];
562       buf[nbuf_end]=digit;
563       nbuf_start++;
564       nbuf_end--;
565     }
566   }
567   return ret;
568 }
569
570 static struct addrinfo *op_resolve(const char *_host,unsigned _port){
571   struct addrinfo *addrs;
572   struct addrinfo  hints;
573   char             service[6];
574   memset(&hints,0,sizeof(hints));
575   hints.ai_socktype=SOCK_STREAM;
576   hints.ai_flags=AI_NUMERICSERV;
577   OP_ASSERT(_port<=65535U);
578   sprintf(service,"%u",_port);
579   if(OP_LIKELY(!getaddrinfo(_host,service,&hints,&addrs)))return addrs;
580   return NULL;
581 }
582
583 static int op_sock_set_nonblocking(int _fd,int _nonblocking){
584   int flags;
585   flags=fcntl(_fd,F_GETFL);
586   if(OP_UNLIKELY(flags<0))return flags;
587   if(_nonblocking)flags|=O_NONBLOCK;
588   else flags&=~O_NONBLOCK;
589   return fcntl(_fd,F_SETFL,flags);
590 }
591
592 /*Disable/enable write coalescing if we can.
593   We always send whole requests at once and always parse the response headers
594    before sending another one, so normally write coalescing just causes added
595    delay.*/
596 static void op_sock_set_tcp_nodelay(int _fd,int _nodelay){
597 # if defined(TCP_NODELAY)&&(defined(IPPROTO_TCP)||defined(SOL_TCP))
598 #  if defined(IPPROTO_TCP)
599 #   define OP_SO_LEVEL IPPROTO_TCP
600 #  else
601 #   define OP_SO_LEVEL SOL_TCP
602 #  endif
603   int ret;
604   ret=setsockopt(_fd,OP_SO_LEVEL,TCP_NODELAY,&_nodelay,sizeof(_nodelay));
605   /*It doesn't really matter if this call fails, but it would be interesting
606      to hit a case where it does.*/
607   OP_ASSERT(!ret);
608 # endif
609 }
610
611 /*A single physical connection to an HTTP server.
612   We may have several of these open at once.*/
613 struct OpusHTTPConn{
614   /*The current position indicator for this connection.*/
615   opus_int64    pos;
616   /*The position where the current request will end, or -1 if we're reading
617      until EOF (an unseekable stream or the initial HTTP/1.0 request).*/
618   opus_int64    end_pos;
619   /*The position where next request we've sent will start, or -1 if we haven't
620      sent the next request yet.*/
621   opus_int64    next_pos;
622   /*The end of the next request or -1 if we requested the rest of the resource.
623     This is only set to a meaningful value if next_pos is not -1.*/
624   opus_int64    next_end;
625   /*The SSL connection, if this is https.*/
626   SSL          *ssl_conn;
627   /*The next connection in either the LRU or free list.*/
628   OpusHTTPConn *next;
629   /*The last time we blocked for reading from this connection.*/
630   struct timeb  read_time;
631   /*The number of bytes we've read since the last time we blocked.*/
632   opus_int64    read_bytes;
633   /*The estimated throughput of this connection, in bytes/s.*/
634   opus_int64    read_rate;
635   /*The socket we're reading from.*/
636   int           fd;
637   /*The number of remaining requests we are allowed on this connection.*/
638   int           nrequests_left;
639   /*The chunk size to use for pipelining requests.*/
640   opus_int32    chunk_size;
641 };
642
643 static void op_http_conn_init(OpusHTTPConn *_conn){
644   _conn->next_pos=-1;
645   _conn->ssl_conn=NULL;
646   _conn->next=NULL;
647   _conn->fd=-1;
648 }
649
650 static void op_http_conn_clear(OpusHTTPConn *_conn){
651   if(_conn->ssl_conn!=NULL)SSL_free(_conn->ssl_conn);
652   /*SSL frees the BIO for us.*/
653   if(_conn->fd>=0)close(_conn->fd);
654 }
655
656 /*The global stream state.*/
657 struct OpusHTTPStream{
658   /*The list of connections.*/
659   OpusHTTPConn     conns[OP_NCONNS_MAX];
660   /*The context object used as a framework for TLS/SSL functions.*/
661   SSL_CTX         *ssl_ctx;
662   /*The cached session to reuse for future connections.*/
663   SSL_SESSION     *ssl_session;
664   /*The LRU list (ordered from MRU to LRU) of currently connected
665      connections.*/
666   OpusHTTPConn    *lru_head;
667   /*The free list.*/
668   OpusHTTPConn    *free_head;
669   /*The URL to connect to.*/
670   OpusParsedURL    url;
671   /*Information about the address we connected to.*/
672   struct addrinfo  addr_info;
673   /*The address we connected to.*/
674   union{
675     struct sockaddr     s;
676     struct sockaddr_in  v4;
677     struct sockaddr_in6 v6;
678   }                addr;
679   /*A buffer used to build HTTP requests.*/
680   OpusStringBuf    request;
681   /*A buffer used to build proxy CONNECT requests.*/
682   OpusStringBuf    proxy_connect;
683   /*A buffer used to receive the response headers.*/
684   OpusStringBuf    response;
685   /*The Content-Length, if specified, or -1 otherwise.
686     This will always be specified for seekable streams.*/
687   opus_int64       content_length;
688   /*The position indicator used when no connection is active.*/
689   opus_int64       pos;
690   /*The connection we're currently reading from.
691     This can be -1 if no connection is active.*/
692   int              cur_conni;
693   /*Whether or not the server supports range requests.*/
694   int              seekable;
695   /*Whether or not the server supports HTTP/1.1 with persistent connections.*/
696   int              pipeline;
697   /*The offset of the tail of the request.
698     Only the offset in the Range: header appears after this, allowing us to
699      quickly edit the request to ask for a new range.*/
700   int              request_tail;
701   /*The estimated time required to open a new connection, in milliseconds.*/
702   opus_int32       connect_rate;
703 };
704
705 static void op_http_stream_init(OpusHTTPStream *_stream){
706   OpusHTTPConn **pnext;
707   int ci;
708   pnext=&_stream->free_head;
709   for(ci=0;ci<OP_NCONNS_MAX;ci++){
710     op_http_conn_init(_stream->conns+ci);
711     *pnext=_stream->conns+ci;
712     pnext=&_stream->conns[ci].next;
713   }
714   _stream->ssl_ctx=NULL;
715   _stream->ssl_session=NULL;
716   _stream->lru_head=NULL;
717   op_parsed_url_init(&_stream->url);
718   op_sb_init(&_stream->request);
719   op_sb_init(&_stream->proxy_connect);
720   op_sb_init(&_stream->response);
721   _stream->seekable=0;
722 }
723
724 /*Close the connection and move it to the free list.
725   _stream:     The stream containing the free list.
726   _conn:       The connection to close.
727   _penxt:      The linked-list pointer currently pointing to this connection.
728   _gracefully: Whether or not to shut down cleanly.*/
729 static void op_http_conn_close(OpusHTTPStream *_stream,OpusHTTPConn *_conn,
730  OpusHTTPConn **_pnext,int _gracefully){
731   /*If we don't shut down gracefully, the server MUST NOT re-use our session
732      according to RFC 2246, because it can't tell the difference between an
733      abrupt close and a truncation attack.
734     So we shut down gracefully if we can.
735     However, we will not wait if this would block (it's not worth the savings
736      from session resumption to do so).
737     Clients (that's us) MAY resume a TLS session that ended with an incomplete
738      close, according to RFC 2818, so that's no reason to make sure the server
739      shut things down gracefully.
740     It also says "client implementations MUST treat any premature closes as
741      errors and the data received as potentially truncated," but libopusfile
742      treats errors and potentially truncated data in unseekable streams just
743      like a normal EOF.
744     We warn about this in the docs, and give some suggestions if you truly want
745      to avoid truncation attacks.*/
746   if(_gracefully&&_conn->ssl_conn!=NULL)SSL_shutdown(_conn->ssl_conn);
747   op_http_conn_clear(_conn);
748   _conn->next_pos=-1;
749   _conn->ssl_conn=NULL;
750   _conn->fd=-1;
751   OP_ASSERT(*_pnext==_conn);
752   *_pnext=_conn->next;
753   _conn->next=_stream->free_head;
754   _stream->free_head=_conn;
755 }
756
757 static void op_http_stream_clear(OpusHTTPStream *_stream){
758   while(_stream->lru_head!=NULL){
759     op_http_conn_close(_stream,_stream->lru_head,&_stream->lru_head,0);
760   }
761   if(_stream->ssl_session!=NULL)SSL_SESSION_free(_stream->ssl_session);
762   if(_stream->ssl_ctx!=NULL)SSL_CTX_free(_stream->ssl_ctx);
763   op_sb_clear(&_stream->response);
764   op_sb_clear(&_stream->proxy_connect);
765   op_sb_clear(&_stream->request);
766   op_parsed_url_clear(&_stream->url);
767 }
768
769 static int op_http_conn_write_fully(OpusHTTPConn *_conn,
770  const char *_buf,int _buf_size){
771   struct pollfd  fd;
772   SSL           *ssl_conn;
773   fd.fd=_conn->fd;
774   ssl_conn=_conn->ssl_conn;
775   while(_buf_size>0){
776     int err;
777     if(ssl_conn!=NULL){
778       int ret;
779       ret=SSL_write(ssl_conn,_buf,_buf_size);
780       if(ret>0){
781         /*Wrote some data.*/
782         _buf+=ret;
783         _buf_size-=ret;
784         continue;
785       }
786       /*Connection closed.*/
787       else if(ret==0)return OP_FALSE;
788       err=SSL_get_error(ssl_conn,ret);
789       /*Yes, renegotiations can cause SSL_write() to block for reading.*/
790       if(err==SSL_ERROR_WANT_READ)fd.events=POLLIN;
791       else if(err==SSL_ERROR_WANT_WRITE)fd.events=POLLOUT;
792       else return OP_FALSE;
793     }
794     else{
795       ssize_t ret;
796       errno=0;
797       ret=write(fd.fd,_buf,_buf_size);
798       if(ret>0){
799         _buf+=ret;
800         _buf_size-=ret;
801         continue;
802       }
803       err=errno;
804       if(err!=EAGAIN&&err!=EWOULDBLOCK)return OP_FALSE;
805       fd.events=POLLOUT;
806     }
807     if(poll(&fd,1,OP_POLL_TIMEOUT_MS)<=0)return OP_FALSE;
808   }
809   return 0;
810 }
811
812 static int op_http_conn_estimate_available(OpusHTTPConn *_conn){
813   int available;
814   int ret;
815   ret=ioctl(_conn->fd,FIONREAD,&available);
816   if(ret<0)available=0;
817   /*This requires the SSL read_ahead flag to be unset to work.
818     We ignore partial records as well as the protocol overhead for any pending
819      bytes.
820     This means we might return somewhat less than can truly be read without
821      blocking (if there's a partial record).
822     This is okay, because we're using this value to estimate network transfer
823      time, and we _have_ already received those bytes.
824     We also might return slightly more (due to protocol overhead), but that's
825      small enough that it probably doesn't matter.*/
826   if(_conn->ssl_conn!=NULL)available+=SSL_pending(_conn->ssl_conn);
827   return available;
828 }
829
830 static opus_int32 op_time_diff_ms(const struct timeb *_end,
831  const struct timeb *_start){
832   opus_int64 dtime;
833   dtime=_end->time-_start->time;
834   OP_ASSERT(_end->millitm<1000);
835   OP_ASSERT(_start->millitm<1000);
836   if(OP_UNLIKELY(dtime>(0x7FFFFFFF-1000)/1000))return 0x7FFFFFFF;
837   if(OP_UNLIKELY(dtime<(-0x7FFFFFFF+999)/1000))return -0x7FFFFFFF-1;
838   return (opus_int32)dtime*1000+_end->millitm-_start->millitm;
839 }
840
841 /*Update the read rate estimate for this connection.*/
842 static void op_http_conn_read_rate_update(OpusHTTPConn *_conn){
843   struct timeb read_time;
844   opus_int32   read_delta_ms;
845   opus_int64   read_delta_bytes;
846   opus_int64   read_rate;
847   int          ret;
848   read_delta_bytes=_conn->read_bytes;
849   if(read_delta_bytes<=0)return;
850   ret=ftime(&read_time);
851   OP_ASSERT(!ret);
852   read_delta_ms=op_time_diff_ms(&read_time,&_conn->read_time);
853   read_rate=_conn->read_rate;
854   read_delta_ms=OP_MAX(read_delta_ms,1);
855   read_rate+=read_delta_bytes*1000/read_delta_ms-read_rate+4>>3;
856   *&_conn->read_time=*&read_time;
857   _conn->read_bytes=0;
858   _conn->read_rate=read_rate;
859 }
860
861 /*Tries to read from the given connection.
862   [out] _buf: Returns the data read.
863   _buf_size:  The size of the buffer.
864   _blocking:  Whether or not to block until some data is retrieved.
865   Return: A positive number of bytes read on success.
866           0:        The read would block, or the connection was closed.
867           OP_EREAD: There was a fatal read error.*/
868 static int op_http_conn_read(OpusHTTPConn *_conn,
869  unsigned char *_buf,int _buf_size,int _blocking){
870   struct pollfd  fd;
871   SSL           *ssl_conn;
872   int            nread;
873   int            nread_unblocked;
874   fd.fd=_conn->fd;
875   ssl_conn=_conn->ssl_conn;
876   nread=nread_unblocked=0;
877   do{
878     int err;
879     if(ssl_conn!=NULL){
880       int ret;
881       ret=SSL_read(ssl_conn,_buf+nread,_buf_size-nread);
882       OP_ASSERT(ret<=_buf_size-nread);
883       if(ret>0){
884         /*Read some data.
885           Keep going to see if there's more.*/
886         nread+=ret;
887         nread_unblocked+=ret;
888         continue;
889       }
890       /*If we already read some data, return it right now.*/
891       if(nread>0)break;
892       err=SSL_get_error(ssl_conn,ret);
893       if(ret==0){
894         /*Connection close.
895           Check for a clean shutdown to prevent truncation attacks.
896           This check always succeeds for SSLv2, as it has no "close notify"
897            message and thus can't verify an orderly shutdown.*/
898         return err==SSL_ERROR_ZERO_RETURN?0:OP_EREAD;
899       }
900       if(err==SSL_ERROR_WANT_READ)fd.events=POLLIN;
901       /*Yes, renegotiations can cause SSL_read() to block for writing.*/
902       else if(err==SSL_ERROR_WANT_WRITE)fd.events=POLLOUT;
903       /*Some other error.*/
904       else return OP_EREAD;
905     }
906     else{
907       ssize_t ret;
908       errno=0;
909       ret=read(fd.fd,_buf+nread,_buf_size-nread);
910       OP_ASSERT(ret<=_buf_size-nread);
911       if(ret>0){
912         /*Read some data.
913           Keep going to see if there's more.*/
914         nread+=ret;
915         nread_unblocked+=ret;
916         continue;
917       }
918       /*If we already read some data or the connection was closed, return
919          right now.*/
920       if(ret==0||nread>0)break;
921       err=errno;
922       if(err!=EAGAIN&&err!=EWOULDBLOCK)return OP_EREAD;
923       fd.events=POLLIN;
924     }
925     _conn->read_bytes+=nread_unblocked;
926     op_http_conn_read_rate_update(_conn);
927     nread_unblocked=0;
928     if(!_blocking)break;
929     /*Need to wait to get any data at all.*/
930     if(poll(&fd,1,OP_POLL_TIMEOUT_MS)<=0)return OP_EREAD;
931   }
932   while(nread<_buf_size);
933   _conn->read_bytes+=nread_unblocked;
934   return nread;
935 }
936
937 /*Tries to look at the pending data for a connection without consuming it.
938   [out] _buf: Returns the data at which we're peeking.
939   _buf_size:  The size of the buffer.*/
940 static int op_http_conn_peek(OpusHTTPConn *_conn,
941  char *_buf,int _buf_size){
942   struct pollfd   fd;
943   SSL            *ssl_conn;
944   int             ret;
945   fd.fd=_conn->fd;
946   ssl_conn=_conn->ssl_conn;
947   for(;;){
948     int err;
949     if(ssl_conn!=NULL){
950       ret=SSL_peek(ssl_conn,_buf,_buf_size);
951       /*Either saw some data or the connection was closed.*/
952       if(ret>=0)return ret;
953       err=SSL_get_error(ssl_conn,ret);
954       if(err==SSL_ERROR_WANT_READ)fd.events=POLLIN;
955       /*Yes, renegotiations can cause SSL_peek() to block for writing.*/
956       else if(err==SSL_ERROR_WANT_WRITE)fd.events=POLLOUT;
957       else return 0;
958     }
959     else{
960       errno=0;
961       ret=(int)recv(fd.fd,_buf,_buf_size,MSG_PEEK);
962       /*Either saw some data or the connection was closed.*/
963       if(ret>=0)return ret;
964       err=errno;
965       if(err!=EAGAIN&&err!=EWOULDBLOCK)return 0;
966       fd.events=POLLIN;
967     }
968     /*Need to wait to get any data at all.*/
969     if(poll(&fd,1,OP_POLL_TIMEOUT_MS)<=0)return 0;
970   }
971 }
972
973 /*When parsing response headers, RFC 2616 mandates that all lines end in CR LF.
974   However, even in the year 2012, I have seen broken servers use just a LF.
975   This is the evil that Postel's advice from RFC 761 breeds.*/
976
977 /*Reads the entirety of a response to an HTTP request into the response buffer.
978   Actual parsing and validation is done later.
979   Return: The number of bytes in the response on success, OP_EREAD if the
980            connection was closed before reading any data, or another negative
981            value on any other error.*/
982 static int op_http_conn_read_response(OpusHTTPConn *_conn,
983  OpusStringBuf *_response){
984   int ret;
985   _response->nbuf=0;
986   ret=op_sb_ensure_capacity(_response,OP_RESPONSE_SIZE_MIN);
987   if(OP_UNLIKELY(ret<0))return ret;
988   for(;;){
989     char *buf;
990     int   size;
991     int   capacity;
992     int   read_limit;
993     int   terminated;
994     size=_response->nbuf;
995     capacity=_response->cbuf-1;
996     if(OP_UNLIKELY(size>=capacity)){
997       ret=op_sb_grow(_response,OP_RESPONSE_SIZE_MAX);
998       if(OP_UNLIKELY(ret<0))return ret;
999       capacity=_response->cbuf-1;
1000       /*The response was too large.
1001         This prevents a bad server from running us out of memory.*/
1002       if(OP_UNLIKELY(size>=capacity))return OP_EIMPL;
1003     }
1004     buf=_response->buf;
1005     ret=op_http_conn_peek(_conn,buf+size,capacity-size);
1006     if(OP_UNLIKELY(ret<=0))return size<=0?OP_EREAD:OP_FALSE;
1007     /*We read some data.*/
1008     /*Make sure the starting characters are "HTTP".
1009       Otherwise we could wind up waiting forever for a response from
1010        something that is not an HTTP server.*/
1011     if(size<4&&op_strncasecmp(buf,"HTTP",OP_MIN(size+ret,4))!=0){
1012       return OP_FALSE;
1013     }
1014     /*How far can we read without passing the "\r\n\r\n" terminator?*/
1015     buf[size+ret]='\0';
1016     terminated=0;
1017     for(read_limit=OP_MAX(size-3,0);read_limit<size+ret;read_limit++){
1018       /*We don't look for the leading '\r' thanks to broken servers.*/
1019       if(buf[read_limit]=='\n'){
1020         if(buf[read_limit+1]=='\r'&&OP_LIKELY(buf[read_limit+2]=='\n')){
1021           terminated=3;
1022           break;
1023         }
1024         /*This case is for broken servers.*/
1025         else if(OP_UNLIKELY(buf[read_limit+1]=='\n')){
1026           terminated=2;
1027           break;
1028         }
1029       }
1030     }
1031     read_limit+=terminated;
1032     OP_ASSERT(size<=read_limit);
1033     OP_ASSERT(read_limit<=size+ret);
1034     /*Actually consume that data.*/
1035     ret=op_http_conn_read(_conn,(unsigned char *)buf+size,read_limit-size,1);
1036     if(OP_UNLIKELY(ret<=0))return OP_FALSE;
1037     size+=ret;
1038     buf[size]='\0';
1039     _response->nbuf=size;
1040     /*We found the terminator and read all the data up to and including it.*/
1041     if(terminated&&OP_LIKELY(size>=read_limit))return size;
1042   }
1043   return OP_EIMPL;
1044 }
1045
1046 # define OP_HTTP_DIGIT "0123456789"
1047
1048 /*The Reason-Phrase is not allowed to contain control characters, except
1049    horizontal tab (HT: \011).*/
1050 # define OP_HTTP_CREASON_PHRASE \
1051  "\001\002\003\004\005\006\007\010\012\013\014\015\016\017\020\021" \
1052  "\022\023\024\025\026\027\030\031\032\033\034\035\036\037\177"
1053
1054 # define OP_HTTP_CTLS \
1055  "\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020" \
1056  "\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\177"
1057
1058 /*This also includes '\t', but we get that from OP_HTTP_CTLS.*/
1059 # define OP_HTTP_SEPARATORS " \"(),/:;<=>?@[\\]{}"
1060
1061 /*TEXT can also include LWS, but that has structure, so we parse it
1062    separately.*/
1063 # define OP_HTTP_CTOKEN OP_HTTP_CTLS OP_HTTP_SEPARATORS
1064
1065 /*Return: The amount of linear white space (LWS) at the start of _s.*/
1066 static int op_http_lwsspn(const char *_s){
1067   int i;
1068   for(i=0;;){
1069     if(_s[0]=='\r'&&_s[1]=='\n'&&(_s[2]=='\t'||_s[2]==' '))i+=3;
1070     /*This case is for broken servers.*/
1071     else if(_s[0]=='\n'&&(_s[1]=='\t'||_s[1]==' '))i+=2;
1072     else if(_s[i]=='\t'||_s[i]==' ')i++;
1073     else return i;
1074   }
1075 }
1076
1077 static char *op_http_parse_status_line(int *_v1_1_compat,
1078  char **_status_code,char *_response){
1079   char   *next;
1080   char   *status_code;
1081   int     v1_1_compat;
1082   size_t  d;
1083   /*RFC 2616 Section 6.1 does not say that the tokens in the Status-Line cannot
1084      be separated by optional LWS, but since it specifically calls out where
1085      spaces are to be placed and that CR and LF are not allowed except at the
1086      end, I am assuming this to be true.*/
1087   /*We already validated that this starts with "HTTP"*/
1088   OP_ASSERT(op_strncasecmp(_response,"HTTP",4)==0);
1089   next=_response+4;
1090   if(OP_UNLIKELY(*next++!='/'))return NULL;
1091   d=strspn(next,OP_HTTP_DIGIT);
1092   /*"Leading zeros MUST be ignored by recipients."*/
1093   while(*next=='0'){
1094     next++;
1095     OP_ASSERT(d>0);
1096     d--;
1097   }
1098   /*We only support version 1.x*/
1099   if(OP_UNLIKELY(d!=1)||OP_UNLIKELY(*next++!='1'))return NULL;
1100   if(OP_UNLIKELY(*next++!='.'))return NULL;
1101   d=strspn(next,OP_HTTP_DIGIT);
1102   if(OP_UNLIKELY(d<=0))return NULL;
1103   /*"Leading zeros MUST be ignored by recipients."*/
1104   while(*next=='0'){
1105     next++;
1106     OP_ASSERT(d>0);
1107     d--;
1108   }
1109   /*We don't need to parse the version number.
1110     Any non-zero digit means it's greater than 1.*/
1111   v1_1_compat=d>0;
1112   next+=d;
1113   if(OP_UNLIKELY(*next++!=' '))return NULL;
1114   status_code=next;
1115   d=strspn(next,OP_HTTP_DIGIT);
1116   if(OP_UNLIKELY(d!=3))return NULL;
1117   next+=d;
1118   /*The Reason-Phrase can be empty, but the space must be here.*/
1119   if(OP_UNLIKELY(*next++!=' '))return NULL;
1120   next+=strcspn(next,OP_HTTP_CREASON_PHRASE);
1121   /*We are not mandating this be present thanks to broken servers.*/
1122   if(OP_LIKELY(*next=='\r'))next++;
1123   if(OP_UNLIKELY(*next++!='\n'))return NULL;
1124   if(_v1_1_compat!=NULL)*_v1_1_compat=v1_1_compat;
1125   *_status_code=status_code;
1126   return next;
1127 }
1128
1129 /*Get the next response header.
1130   [out] _header: The header token, NUL-terminated, with leading and trailing
1131                   whitespace stripped, and converted to lower case (to simplify
1132                   case-insensitive comparisons), or NULL if there are no more
1133                   response headers.
1134   [out] _cdr:    The remaining contents of the header, excluding the initial
1135                   colon (':') and the terminating CRLF ("\r\n"),
1136                   NUL-terminated, and with leading and trailing whitespace
1137                   stripped, or NULL if there are no more response headers.
1138   [inout] _s:    On input, this points to the start of the current line of the
1139                   response headers.
1140                  On output, it points to the start of the first line following
1141                   this header, or NULL if there are no more response headers.
1142   Return: 0 on success, or a negative value on failure.*/
1143 static int op_http_get_next_header(char **_header,char **_cdr,char **_s){
1144   char   *header;
1145   char   *header_end;
1146   char   *cdr;
1147   char   *cdr_end;
1148   char   *next;
1149   size_t  d;
1150   next=*_s;
1151   /*The second case is for broken servers.*/
1152   if(next[0]=='\r'&&next[1]=='\n'||OP_UNLIKELY(next[0]=='\n')){
1153     /*No more headers.*/
1154     *_header=NULL;
1155     *_cdr=NULL;
1156     *_s=NULL;
1157     return 0;
1158   }
1159   header=next+op_http_lwsspn(next);
1160   d=strcspn(header,OP_HTTP_CTOKEN);
1161   if(OP_UNLIKELY(d<=0))return OP_FALSE;
1162   header_end=header+d;
1163   next=header_end+op_http_lwsspn(header_end);
1164   if(OP_UNLIKELY(*next++!=':'))return OP_FALSE;
1165   next+=op_http_lwsspn(next);
1166   cdr=next;
1167   do{
1168     cdr_end=next+strcspn(next,OP_HTTP_CTLS);
1169     next=cdr_end+op_http_lwsspn(cdr_end);
1170   }
1171   while(next>cdr_end);
1172   /*We are not mandating this be present thanks to broken servers.*/
1173   if(OP_LIKELY(*next=='\r'))next++;
1174   if(OP_UNLIKELY(*next++!='\n'))return OP_FALSE;
1175   *header_end='\0';
1176   *cdr_end='\0';
1177   /*Field names are case-insensitive.*/
1178   op_string_tolower(header);
1179   *_header=header;
1180   *_cdr=cdr;
1181   *_s=next;
1182   return 0;
1183 }
1184
1185 static opus_int64 op_http_parse_nonnegative_int64(const char **_next,
1186  const char *_cdr){
1187   const char *next;
1188   opus_int64  content_length;
1189   int         i;
1190   next=_cdr+strspn(_cdr,OP_HTTP_DIGIT);
1191   *_next=next;
1192   if(OP_UNLIKELY(next<=_cdr))return OP_FALSE;
1193   while(*_cdr=='0')_cdr++;
1194   if(OP_UNLIKELY(next-_cdr>19))return OP_EIMPL;
1195   content_length=0;
1196   for(i=0;i<next-_cdr;i++){
1197     int digit;
1198     digit=_cdr[i]-'0';
1199     /*Check for overflow.*/
1200     if(OP_UNLIKELY(content_length>(OP_INT64_MAX-9)/10+(digit<=7))){
1201       return OP_EIMPL;
1202     }
1203     content_length=content_length*10+digit;
1204   }
1205   return content_length;
1206 }
1207
1208 static opus_int64 op_http_parse_content_length(const char *_cdr){
1209   const char *next;
1210   opus_int64  content_length;
1211   content_length=op_http_parse_nonnegative_int64(&next,_cdr);
1212   if(OP_UNLIKELY(*next!='\0'))return OP_FALSE;
1213   return content_length;
1214 }
1215
1216 static int op_http_parse_content_range(opus_int64 *_first,opus_int64 *_last,
1217  opus_int64 *_length,const char *_cdr){
1218   opus_int64 first;
1219   opus_int64 last;
1220   opus_int64 length;
1221   size_t     d;
1222   if(OP_UNLIKELY(op_strncasecmp(_cdr,"bytes",5)!=0))return OP_FALSE;
1223   _cdr+=5;
1224   d=op_http_lwsspn(_cdr);
1225   if(OP_UNLIKELY(d<=0))return OP_FALSE;
1226   _cdr+=d;
1227   if(*_cdr!='*'){
1228     first=op_http_parse_nonnegative_int64(&_cdr,_cdr);
1229     if(OP_UNLIKELY(first<0))return (int)first;
1230     _cdr+=op_http_lwsspn(_cdr);
1231     if(*_cdr++!='-')return OP_FALSE;
1232     _cdr+=op_http_lwsspn(_cdr);
1233     last=op_http_parse_nonnegative_int64(&_cdr,_cdr);
1234     if(OP_UNLIKELY(last<0))return (int)last;
1235     _cdr+=op_http_lwsspn(_cdr);
1236   }
1237   else{
1238     /*This is for a 416 response (Requested range not satisfiable).*/
1239     first=last=-1;
1240     _cdr++;
1241   }
1242   if(OP_UNLIKELY(*_cdr++!='/'))return OP_FALSE;
1243   if(*_cdr!='*'){
1244     length=op_http_parse_nonnegative_int64(&_cdr,_cdr);
1245     if(OP_UNLIKELY(length<0))return (int)length;
1246   }
1247   else{
1248     /*The total length is unspecified.*/
1249     _cdr++;
1250     length=-1;
1251   }
1252   if(OP_UNLIKELY(*_cdr!='\0'))return OP_FALSE;
1253   if(OP_UNLIKELY(last<first))return OP_FALSE;
1254   if(length>=0&&OP_UNLIKELY(last>=length))return OP_FALSE;
1255   *_first=first;
1256   *_last=last;
1257   *_length=length;
1258   return 0;
1259 }
1260
1261 /*Parse the Connection response header and look for a "close" token.
1262   Return: 1 if a "close" token is found, 0 if it's not found, and a negative
1263            value on error.*/
1264 static int op_http_parse_connection(char *_cdr){
1265   size_t d;
1266   int    ret;
1267   ret=0;
1268   for(;;){
1269     d=strcspn(_cdr,OP_HTTP_CTOKEN);
1270     if(OP_UNLIKELY(d<=0))return OP_FALSE;
1271     if(op_strncasecmp(_cdr,"close",(int)d)==0)ret=1;
1272     /*We're supposed to strip and ignore any headers mentioned in the
1273        Connection header if this response is from an HTTP/1.0 server (to
1274        work around forwarding of hop-by-hop headers by old proxies), but the
1275        only hop-by-hop header we look at is Connection itself.
1276       Everything else is a well-defined end-to-end header, and going back and
1277        undoing the things we did based on already-examined headers would be
1278        hard (since we only scan them once, in a destructive manner).
1279       Therefore we just ignore all the other tokens.*/
1280     _cdr+=d;
1281     d=op_http_lwsspn(_cdr);
1282     if(d<=0)break;
1283     _cdr+=d;
1284   }
1285   return OP_UNLIKELY(*_cdr!='\0')?OP_FALSE:ret;
1286 }
1287
1288 typedef int (*op_ssl_step_func)(SSL *_ssl_conn);
1289
1290 /*Try to run an SSL function to completion (blocking if necessary).*/
1291 static int op_do_ssl_step(SSL *_ssl_conn,int _fd,op_ssl_step_func _step){
1292   struct pollfd fd;
1293   fd.fd=_fd;
1294   for(;;){
1295     int ret;
1296     int err;
1297     ret=(*_step)(_ssl_conn);
1298     if(ret>=0)return ret;
1299     err=SSL_get_error(_ssl_conn,ret);
1300     if(err==SSL_ERROR_WANT_READ)fd.events=POLLIN;
1301     else if(err==SSL_ERROR_WANT_WRITE)fd.events=POLLOUT;
1302     else return OP_FALSE;
1303     if(poll(&fd,1,OP_POLL_TIMEOUT_MS)<=0)return OP_FALSE;
1304   }
1305 }
1306
1307 /*Implement a BIO type that just indicates every operation should be retried.
1308   We use this when initializing an SSL connection via a proxy to allow the
1309    initial handshake to proceed all the way up to the first read attempt, and
1310    then return.
1311   This allows the TLS client hello message to be pipelined with the HTTP
1312    CONNECT request.*/
1313
1314 static int op_bio_retry_write(BIO *_b,const char *_buf,int _num){
1315   (void)_buf;
1316   (void)_num;
1317   BIO_clear_retry_flags(_b);
1318   BIO_set_retry_write(_b);
1319   return -1;
1320 }
1321
1322 static int op_bio_retry_read(BIO *_b,char *_buf,int _num){
1323   (void)_buf;
1324   (void)_num;
1325   BIO_clear_retry_flags(_b);
1326   BIO_set_retry_read(_b);
1327   return -1;
1328 }
1329
1330 static int op_bio_retry_puts(BIO *_b,const char *_str){
1331   return op_bio_retry_write(_b,_str,0);
1332 }
1333
1334 static long op_bio_retry_ctrl(BIO *_b,int _cmd,long _num,void *_ptr){
1335   long ret;
1336   (void)_b;
1337   (void)_num;
1338   (void)_ptr;
1339   ret=0;
1340   switch(_cmd){
1341     case BIO_CTRL_RESET:
1342     case BIO_C_RESET_READ_REQUEST:{
1343       BIO_clear_retry_flags(_b);
1344       /*Fall through.*/
1345     }
1346     case BIO_CTRL_EOF:
1347     case BIO_CTRL_SET:
1348     case BIO_CTRL_SET_CLOSE:
1349     case BIO_CTRL_FLUSH:
1350     case BIO_CTRL_DUP:{
1351       ret=1;
1352     }break;
1353   }
1354   return ret;
1355 }
1356
1357 static int op_bio_retry_new(BIO *_b){
1358   _b->init=1;
1359   _b->num=0;
1360   _b->ptr=NULL;
1361   return 1;
1362 }
1363
1364 static int op_bio_retry_free(BIO *_b){
1365   return _b!=NULL;
1366 }
1367
1368 /*This is not const because OpenSSL doesn't allow it, even though it won't
1369    write to it.*/
1370 static BIO_METHOD op_bio_retry_method={
1371   BIO_TYPE_NULL,
1372   "retry",
1373   op_bio_retry_write,
1374   op_bio_retry_read,
1375   op_bio_retry_puts,
1376   NULL,
1377   op_bio_retry_ctrl,
1378   op_bio_retry_new,
1379   op_bio_retry_free,
1380   NULL
1381 };
1382
1383 /*Establish a CONNECT tunnel and pipeline the start of the TLS handshake for
1384    proxying https URL requests.*/
1385 int op_http_conn_establish_tunnel(OpusHTTPStream *_stream,
1386  OpusHTTPConn *_conn,int _fd,SSL *_ssl_conn,BIO *_ssl_bio){
1387   BIO  *retry_bio;
1388   char *status_code;
1389   char *next;
1390   int   ret;
1391   _conn->ssl_conn=NULL;
1392   _conn->fd=_fd;
1393   OP_ASSERT(_stream->proxy_connect.nbuf>0);
1394   ret=op_http_conn_write_fully(_conn,
1395    _stream->proxy_connect.buf,_stream->proxy_connect.nbuf);
1396   if(OP_UNLIKELY(ret<0))return ret;
1397   retry_bio=BIO_new(&op_bio_retry_method);
1398   if(OP_UNLIKELY(retry_bio==NULL))return OP_EFAULT;
1399   SSL_set_bio(_ssl_conn,retry_bio,_ssl_bio);
1400   SSL_set_connect_state(_ssl_conn);
1401   ret=SSL_connect(_ssl_conn);
1402   /*This shouldn't succeed, since we can't read yet.*/
1403   OP_ASSERT(ret<0);
1404   SSL_set_bio(_ssl_conn,_ssl_bio,_ssl_bio);
1405   /*Only now do we disable write coalescing, to allow the CONNECT
1406      request and the start of the TLS handshake to be combined.*/
1407   op_sock_set_tcp_nodelay(_fd,1);
1408   ret=op_http_conn_read_response(_conn,&_stream->response);
1409   if(OP_UNLIKELY(ret<0))return ret;
1410   next=op_http_parse_status_line(NULL,&status_code,_stream->response.buf);
1411   /*According to RFC 2817, "Any successful (2xx) response to a
1412      CONNECT request indicates that the proxy has established a
1413      connection to the requested host and port.*/
1414   if(OP_UNLIKELY(next==NULL)||OP_UNLIKELY(status_code[0]!='2'))return OP_FALSE;
1415   return 0;
1416 }
1417
1418 /*Perform the TLS handshake on a new connection.*/
1419 int op_http_conn_start_tls(OpusHTTPStream *_stream,OpusHTTPConn *_conn,
1420  int _fd,SSL *_ssl_conn){
1421   BIO *ssl_bio;
1422   int  ret;
1423   ssl_bio=BIO_new_socket(_fd,BIO_NOCLOSE);
1424   if(OP_LIKELY(ssl_bio==NULL))return OP_FALSE;
1425 # if !defined(OPENSSL_NO_TLSEXT)
1426   /*Support for RFC 6066 Server Name Indication.*/
1427   SSL_set_tlsext_host_name(_ssl_conn,_stream->url.host);
1428 # endif
1429   /*Resume a previous session if available.*/
1430   if(_stream->ssl_session!=NULL){
1431     SSL_set_session(_ssl_conn,_stream->ssl_session);
1432   }
1433   /*If we're proxying, establish the CONNECT tunnel.*/
1434   if(_stream->proxy_connect.nbuf>0){
1435     ret=op_http_conn_establish_tunnel(_stream,_conn,
1436      _fd,_ssl_conn,ssl_bio);
1437     if(OP_UNLIKELY(ret<0))return ret;
1438   }
1439   else{
1440     /*Otherwise, just use this socket directly.*/
1441     op_sock_set_tcp_nodelay(_fd,1);
1442     SSL_set_bio(_ssl_conn,ssl_bio,ssl_bio);
1443     SSL_set_connect_state(_ssl_conn);
1444   }
1445   ret=op_do_ssl_step(_ssl_conn,_fd,SSL_connect);
1446   if(OP_UNLIKELY(ret<=0))return OP_FALSE;
1447   if(_stream->ssl_session==NULL){
1448     /*Save a session for later resumption.*/
1449     ret=op_do_ssl_step(_ssl_conn,_fd,SSL_do_handshake);
1450     if(OP_UNLIKELY(ret<=0))return OP_FALSE;
1451     _stream->ssl_session=SSL_get1_session(_ssl_conn);
1452   }
1453   _conn->ssl_conn=_ssl_conn;
1454   _conn->fd=_fd;
1455   _conn->nrequests_left=OP_PIPELINE_MAX_REQUESTS;
1456   return 0;
1457 }
1458
1459 /*Try to start a connection to the next address in the given list of a given
1460    type.
1461   _fd:           The socket to connect with.
1462   [inout] _addr: A pointer to the list of addresses.
1463                  This will be advanced to the first one that matches the given
1464                   address family (possibly the current one).
1465   _ai_family:    The address family to connect to.
1466   Return: 1        If the connection was successful.
1467           0        If the connection is in progress.
1468           OP_FALSE If the connection failed and there were no more addresses
1469                     left to try.
1470                     *_addr will be set to NULL in this case.*/
1471 static int op_sock_connect_next(int _fd,
1472  struct addrinfo **_addr,int _ai_family){
1473   struct addrinfo *addr;
1474   addr=*_addr;
1475   for(;;){
1476     /*Move to the next address of the requested type.*/
1477     for(;addr!=NULL&&addr->ai_family!=_ai_family;addr=addr->ai_next);
1478     *_addr=addr;
1479     /*No more: failure.*/
1480     if(addr==NULL)return OP_FALSE;
1481     if(connect(_fd,addr->ai_addr,addr->ai_addrlen)>=0)return 1;
1482     if(OP_LIKELY(errno==EINPROGRESS))return 0;
1483     addr=addr->ai_next;
1484   }
1485 }
1486
1487 /*The number of address families to try connecting to simultaneously.*/
1488 # define OP_NPROTOS (2)
1489
1490 static int op_http_connect(OpusHTTPStream *_stream,OpusHTTPConn *_conn,
1491  struct addrinfo *_addrs,struct timeb *_start_time){
1492   struct addrinfo *addr;
1493   struct addrinfo *addrs[OP_NPROTOS];
1494   struct pollfd    fds[OP_NPROTOS];
1495   int              ai_family;
1496   int              nprotos;
1497   int              ret;
1498   int              pi;
1499   int              pj;
1500   for(pi=0;pi<OP_NPROTOS;pi++)addrs[pi]=NULL;
1501   addr=_addrs;
1502   /*Try connecting via both IPv4 and IPv6 simultaneously, and keep the first
1503      one that succeeds.*/
1504   for(;addr!=NULL;addr=addr->ai_next){
1505     /*Give IPv6 a slight edge by putting it first in the list.*/
1506     if(addr->ai_family==AF_INET6){
1507       OP_ASSERT(addr->ai_addrlen<=sizeof(struct sockaddr_in6));
1508       if(addrs[0]==NULL)addrs[0]=addr;
1509     }
1510     else if(addr->ai_family==AF_INET){
1511       OP_ASSERT(addr->ai_addrlen<=sizeof(struct sockaddr_in));
1512       if(addrs[1]==NULL)addrs[1]=addr;
1513     }
1514   }
1515   /*Consolidate the list of addresses.*/
1516   for(pi=nprotos=0;pi<OP_NPROTOS;pi++){
1517     if(addrs[pi]!=NULL){
1518       addrs[nprotos]=addrs[pi];
1519       nprotos++;
1520     }
1521   }
1522   /*Pop the connection off the free list and put it on the LRU list.*/
1523   OP_ASSERT(_stream->free_head==_conn);
1524   _stream->free_head=_conn->next;
1525   _conn->next=_stream->lru_head;
1526   _stream->lru_head=_conn;
1527   ret=ftime(_start_time);
1528   OP_ASSERT(!ret);
1529   *&_conn->read_time=*_start_time;
1530   _conn->read_bytes=0;
1531   _conn->read_rate=0;
1532   /*Try to start a connection to each protocol.*/
1533   for(pi=0;pi<nprotos;pi++){
1534     ai_family=addrs[pi]->ai_family;
1535     fds[pi].fd=socket(ai_family,SOCK_STREAM,addrs[pi]->ai_protocol);
1536     fds[pi].events=POLLOUT;
1537     if(OP_LIKELY(fds[pi].fd>=0)){
1538       if(OP_LIKELY(op_sock_set_nonblocking(fds[pi].fd,1)>=0)){
1539         ret=op_sock_connect_next(fds[pi].fd,addrs+pi,ai_family);
1540         if(OP_UNLIKELY(ret>0)){
1541           /*It succeeded right away (technically possible), so stop.*/
1542           nprotos=pi+1;
1543           break;
1544         }
1545         /*Otherwise go on to the next protocol, and skip the clean-up below.*/
1546         else if(ret==0)continue;
1547         /*Tried all the addresses for this protocol.*/
1548       }
1549       /*Clean up the socket.*/
1550       close(fds[pi].fd);
1551     }
1552     /*Remove this protocol from the list.*/
1553     memmove(addrs+pi,addrs+pi+1,sizeof(*addrs)*(nprotos-pi-1));
1554     nprotos--;
1555     pi--;
1556   }
1557   /*Wait for one of the connections to finish.*/
1558   while(pi>=nprotos&&nprotos>0&&poll(fds,nprotos,OP_POLL_TIMEOUT_MS)>0){
1559     for(pi=0;pi<nprotos;pi++){
1560       socklen_t errlen;
1561       int       err;
1562       /*Still waiting...*/
1563       if(!fds[pi].revents)continue;
1564       errlen=sizeof(err);
1565       /*Some platforms will return the pending error in &err and return 0.
1566         Others will put it in errno and return -1.*/
1567       ret=getsockopt(fds[pi].fd,SOL_SOCKET,SO_ERROR,&err,&errlen);
1568       if(ret<0)err=errno;
1569       /*Success!*/
1570       if(err==0||err==EISCONN)break;
1571       /*Move on to the next address for this protocol.*/
1572       ai_family=addrs[pi]->ai_family;
1573       addrs[pi]=addrs[pi]->ai_next;
1574       ret=op_sock_connect_next(fds[pi].fd,addrs+pi,ai_family);
1575       /*It succeeded right away, so stop.*/
1576       if(ret>0)break;
1577       /*Otherwise go on to the next protocol, and skip the clean-up below.*/
1578       else if(ret==0)continue;
1579       /*Tried all the addresses for this protocol.
1580         Remove it from the list.*/
1581       close(fds[pi].fd);
1582       memmove(fds+pi,fds+pi+1,sizeof(*fds)*(nprotos-pi-1));
1583       memmove(addrs+pi,addrs+pi+1,sizeof(*addrs)*(nprotos-pi-1));
1584       nprotos--;
1585       pi--;
1586     }
1587   }
1588   /*Close all the other sockets.*/
1589   for(pj=0;pj<nprotos;pj++)if(pi!=pj)close(fds[pj].fd);
1590   /*If none of them succeeded, we're done.*/
1591   if(pi>=nprotos)return OP_FALSE;
1592   /*Save this address for future connection attempts.*/
1593   if(addrs[pi]!=&_stream->addr_info){
1594     memcpy(&_stream->addr_info,addrs[pi],sizeof(_stream->addr_info));
1595     _stream->addr_info.ai_addr=&_stream->addr.s;
1596     _stream->addr_info.ai_next=NULL;
1597     memcpy(&_stream->addr,addrs[pi]->ai_addr,addrs[pi]->ai_addrlen);
1598   }
1599   if(OP_URL_IS_SSL(&_stream->url)){
1600     SSL *ssl_conn;
1601     /*Start the SSL connection.*/
1602     OP_ASSERT(_stream->ssl_ctx!=NULL);
1603     ssl_conn=SSL_new(_stream->ssl_ctx);
1604     if(OP_LIKELY(ssl_conn!=NULL)){
1605       ret=op_http_conn_start_tls(_stream,_conn,fds[pi].fd,ssl_conn);
1606       if(OP_LIKELY(ret>=0))return ret;
1607       SSL_free(ssl_conn);
1608     }
1609     close(fds[pi].fd);
1610     _conn->fd=-1;
1611     return OP_FALSE;
1612   }
1613   /*Just a normal non-SSL connection.*/
1614   _conn->ssl_conn=NULL;
1615   _conn->fd=fds[pi].fd;
1616   _conn->nrequests_left=OP_PIPELINE_MAX_REQUESTS;
1617   /*Disable write coalescing.
1618     We always send whole requests at once and always parse the response headers
1619      before sending another one.*/
1620   op_sock_set_tcp_nodelay(fds[pi].fd,1);
1621   return 0;
1622 }
1623
1624 # define OP_BASE64_LENGTH(_len) (((_len)+2)/3*4)
1625
1626 static const char BASE64_TABLE[64]={
1627   'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
1628   'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
1629   'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
1630   'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
1631 };
1632
1633 static char *op_base64_encode(char *_dst,const char *_src,int _len){
1634   unsigned s0;
1635   unsigned s1;
1636   unsigned s2;
1637   int      ngroups;
1638   int      i;
1639   ngroups=_len/3;
1640   for(i=0;i<ngroups;i++){
1641     s0=_src[3*i+0];
1642     s1=_src[3*i+1];
1643     s2=_src[3*i+2];
1644     _dst[4*i+0]=BASE64_TABLE[s0>>2];
1645     _dst[4*i+1]=BASE64_TABLE[s0&3<<4|s1>>4];
1646     _dst[4*i+2]=BASE64_TABLE[s1&15<<2|s2>>6];
1647     _dst[4*i+3]=BASE64_TABLE[s2&63];
1648   }
1649   _len-=3*i;
1650   if(_len==1){
1651     s0=_src[3*i+0];
1652     _dst[4*i+0]=BASE64_TABLE[s0>>2];
1653     _dst[4*i+1]=BASE64_TABLE[s0&3<<4];
1654     _dst[4*i+2]='=';
1655     _dst[4*i+3]='=';
1656     i++;
1657   }
1658   else if(_len==2){
1659     s0=_src[3*i+0];
1660     s1=_src[3*i+1];
1661     _dst[4*i+0]=BASE64_TABLE[s0>>2];
1662     _dst[4*i+1]=BASE64_TABLE[s0&3<<4|s1>>4];
1663     _dst[4*i+2]=BASE64_TABLE[s1&15<<2];
1664     _dst[4*i+3]='=';
1665     i++;
1666   }
1667   _dst[4*i]='\0';
1668   return _dst+4*i;
1669 }
1670
1671 /*Construct an HTTP authorization header using RFC 2617's Basic Authentication
1672    Scheme and append it to the given string buffer.*/
1673 static int op_sb_append_basic_auth_header(OpusStringBuf *_sb,
1674  const char *_header,const char *_user,const char *_pass){
1675   int user_len;
1676   int pass_len;
1677   int user_pass_len;
1678   int base64_len;
1679   int nbuf_total;
1680   int ret;
1681   ret=op_sb_append_string(_sb,_header);
1682   ret|=op_sb_append(_sb,": Basic ",8);
1683   user_len=strlen(_user);
1684   pass_len=strlen(_pass);
1685   if(OP_UNLIKELY(pass_len>INT_MAX-user_len))return OP_EFAULT;
1686   if(OP_UNLIKELY(user_len+pass_len>(INT_MAX>>2)*3-3))return OP_EFAULT;
1687   user_pass_len=user_len+1+pass_len;
1688   base64_len=OP_BASE64_LENGTH(user_pass_len);
1689   /*Stick "user:pass" at the end of the buffer so we can Base64 encode it
1690      in-place.*/
1691   nbuf_total=_sb->nbuf;
1692   if(OP_UNLIKELY(base64_len>INT_MAX-nbuf_total))return OP_EFAULT;
1693   nbuf_total+=base64_len;
1694   ret|=op_sb_ensure_capacity(_sb,nbuf_total);
1695   if(OP_UNLIKELY(ret<0))return ret;
1696   _sb->nbuf=nbuf_total-user_pass_len;
1697   ret=op_sb_append(_sb,_user,user_len);
1698   OP_ASSERT(!ret);
1699   ret=op_sb_append(_sb,":",1);
1700   OP_ASSERT(!ret);
1701   ret=op_sb_append(_sb,_pass,pass_len);
1702   OP_ASSERT(!ret);
1703   op_base64_encode(_sb->buf+nbuf_total-base64_len,
1704    _sb->buf+nbuf_total-user_pass_len,user_pass_len);
1705   return op_sb_append(_sb,"\r\n",2);
1706 }
1707
1708 static int op_http_allow_pipelining(const char *_server){
1709   /*Servers known to do bad things with pipelined requests.
1710     This list is taken from Gecko's nsHttpConnection::SupportsPipelining() (in
1711      netwerk/protocol/http/nsHttpConnection.cpp).*/
1712   static const char *BAD_SERVERS[]={
1713     "EFAServer/",
1714     "Microsoft-IIS/4.",
1715     "Microsoft-IIS/5.",
1716     "Netscape-Enterprise/3.",
1717     "Netscape-Enterprise/4.",
1718     "Netscape-Enterprise/5.",
1719     "Netscape-Enterprise/6.",
1720     "WebLogic 3.",
1721     "WebLogic 4.",
1722     "WebLogic 5.",
1723     "WebLogic 6.",
1724     "Winstone Servlet Engine v0."
1725   };
1726 # define NBAD_SERVERS ((int)(sizeof(BAD_SERVERS)/sizeof(*BAD_SERVERS)))
1727   if(*_server>='E'&&*_server<='W'){
1728     int si;
1729     for(si=0;si<NBAD_SERVERS;si++){
1730       if(strncmp(_server,BAD_SERVERS[si],strlen(BAD_SERVERS[si]))==0){
1731         return 0;
1732       }
1733     }
1734   }
1735   return 1;
1736 # undef NBAD_SERVERS
1737 }
1738
1739 static int op_http_stream_open(OpusHTTPStream *_stream,const char *_url,
1740  int _skip_certificate_check,const char *_proxy_host,unsigned _proxy_port,
1741  const char *_proxy_user,const char *_proxy_pass){
1742   struct addrinfo *addrs;
1743   const char      *last_host;
1744   unsigned         last_port;
1745   int              nredirs;
1746   int              ret;
1747   if(_proxy_host!=NULL&&OP_UNLIKELY(_proxy_port>65535U))return OP_EINVAL;
1748   last_host=NULL;
1749   /*We shouldn't have to initialize last_port, but gcc is too dumb to figure
1750      out that last_host!=NULL implies we've already taken one trip through the
1751      loop.*/
1752   last_port=0;
1753   ret=op_parse_url(&_stream->url,_url);
1754   if(OP_UNLIKELY(ret<0))return ret;
1755   for(nredirs=0;nredirs<OP_REDIRECT_LIMIT;nredirs++){
1756     struct timeb  start_time;
1757     struct timeb  end_time;
1758     char         *next;
1759     char         *status_code;
1760     const char   *host;
1761     unsigned      port;
1762     int           minor_version_pos;
1763     int           v1_1_compat;
1764     if(_proxy_host==NULL){
1765       host=_stream->url.host;
1766       port=_stream->url.port;
1767     }
1768     else{
1769       host=_proxy_host;
1770       port=_proxy_port;
1771     }
1772     /*If connecting to the same place as last time, don't re-resolve it.*/
1773     addrs=NULL;
1774     if(last_host!=NULL){
1775       if(strcmp(last_host,host)==0&&last_port==port)addrs=&_stream->addr_info;
1776       else if(_stream->ssl_session!=NULL){
1777         /*Forget any cached SSL session from the last host.*/
1778         SSL_SESSION_free(_stream->ssl_session);
1779         _stream->ssl_session=NULL;
1780       }
1781       if(last_host!=_proxy_host)_ogg_free((void *)last_host);
1782     }
1783     last_host=host;
1784     last_port=port;
1785     /*Initialize the SSL library if necessary.*/
1786     if(OP_URL_IS_SSL(&_stream->url)&&_stream->ssl_ctx==NULL){
1787       SSL_CTX *ssl_ctx;
1788 # if !defined(OPENSSL_NO_LOCKING)
1789       /*The documentation says SSL_library_init() is not reentrant.
1790         We don't want to add our own depenencies on a threading library, and it
1791          appears that it's safe to call OpenSSL's locking functions before the
1792          library is initialized, so that's what we'll do (really OpenSSL should
1793          do this for us).
1794         This doesn't guarantee that _other_ threads in the application aren't
1795          calling SSL_library_init() at the same time, but there's not much we
1796          can do about that.*/
1797       CRYPTO_w_lock(CRYPTO_LOCK_SSL);
1798 # endif
1799       SSL_library_init();
1800       /*Needed to get SHA2 algorithms with old OpenSSL versions.*/
1801       OpenSSL_add_ssl_algorithms();
1802 # if !defined(OPENSSL_NO_LOCKING)
1803       CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
1804 # endif
1805       ssl_ctx=SSL_CTX_new(SSLv23_client_method());
1806       if(ssl_ctx==NULL)return OP_EFAULT;
1807       if(!_skip_certificate_check){
1808         SSL_CTX_set_verify(ssl_ctx,SSL_VERIFY_PEER,NULL);
1809       }
1810       _stream->ssl_ctx=ssl_ctx;
1811       if(_proxy_host!=NULL){
1812         /*We need to establish a CONNECT tunnel to handle https proxying.
1813           Build the request we'll send to do so.*/
1814         ret=op_sb_append(&_stream->proxy_connect,"CONNECT ",8);
1815         ret|=op_sb_append_string(&_stream->proxy_connect,_stream->url.host);
1816         ret|=op_sb_append_port(&_stream->proxy_connect,_stream->url.port);
1817         /*CONNECT requires at least HTTP 1.1.*/
1818         ret|=op_sb_append(&_stream->proxy_connect," HTTP/1.1\r\n",11);
1819         ret|=op_sb_append(&_stream->proxy_connect,"Host: ",6);
1820         ret|=op_sb_append_string(&_stream->proxy_connect,_stream->url.host);
1821         /*The example in RFC 2817 Section 5.2 specifies an explicit port even
1822            when connecting to the default port.
1823           Given that the proxy doesn't know whether we're trying to connect to
1824            an http or an https URL except by the port number, this seems like a
1825            good idea.*/
1826         ret|=op_sb_append_port(&_stream->proxy_connect,_stream->url.port);
1827         ret|=op_sb_append(&_stream->proxy_connect,"\r\n",2);
1828         ret|=op_sb_append(&_stream->proxy_connect,"User-Agent: .\r\n",15);
1829         if(_proxy_user!=NULL&&_proxy_pass!=NULL){
1830           ret|=op_sb_append_basic_auth_header(&_stream->proxy_connect,
1831            "Proxy-Authorization",_proxy_user,_proxy_pass);
1832         }
1833         /*For backwards compatibility.*/
1834         ret|=op_sb_append(&_stream->proxy_connect,
1835          "Proxy-Connection: keep-alive\r\n",30);
1836         ret|=op_sb_append(&_stream->proxy_connect,"\r\n",2);
1837         if(OP_UNLIKELY(ret<0))return ret;
1838       }
1839     }
1840     /*Actually make the connection.*/
1841     if(addrs!=&_stream->addr_info){
1842       addrs=op_resolve(host,port);
1843       if(OP_UNLIKELY(addrs==NULL))return OP_FALSE;
1844     }
1845     ret=op_http_connect(_stream,_stream->conns+0,addrs,&start_time);
1846     if(addrs!=&_stream->addr_info)freeaddrinfo(addrs);
1847     if(OP_UNLIKELY(ret<0))return ret;
1848     /*Build the request to send.*/
1849     _stream->request.nbuf=0;
1850     ret=op_sb_append(&_stream->request,"GET ",4);
1851     ret|=op_sb_append_string(&_stream->request,
1852      _proxy_host!=NULL?_url:_stream->url.path);
1853     /*Send HTTP/1.0 by default for maximum compatibility (so we don't have to
1854        re-try if HTTP/1.1 fails, though it shouldn't, even for a 1.0 server).
1855       This means we aren't conditionally compliant with RFC 2145, because we
1856        violate the requirement that "An HTTP client SHOULD send a request
1857        version equal to the highest version for which the client is at least
1858        conditionally compliant...".
1859       According to RFC 2145, that means we can't claim any compliance with any
1860        IETF HTTP specification.*/
1861     ret|=op_sb_append(&_stream->request," HTTP/1.0\r\n",11);
1862     /*Remember where this is so we can upgrade to HTTP/1.1 if the server
1863        supports it.*/
1864     minor_version_pos=_stream->request.nbuf-3;
1865     ret|=op_sb_append(&_stream->request,"Host: ",6);
1866     ret|=op_sb_append_string(&_stream->request,_stream->url.host);
1867     if(!OP_URL_IS_DEFAULT_PORT(&_stream->url)){
1868       ret|=op_sb_append_port(&_stream->request,_stream->url.port);
1869     }
1870     ret|=op_sb_append(&_stream->request,"\r\n",2);
1871     /*User-Agents have been a bad idea, so send as little as possible.
1872       RFC 2616 requires at least one token in the User-Agent, which must have
1873        at least one character.*/
1874     ret|=op_sb_append(&_stream->request,"User-Agent: .\r\n",15);
1875     if(_proxy_host!=NULL&&!OP_URL_IS_SSL(&_stream->url)
1876      &&_proxy_user!=NULL&&_proxy_pass!=NULL){
1877       ret|=op_sb_append_basic_auth_header(&_stream->request,
1878        "Proxy-Authorization",_proxy_user,_proxy_pass);
1879     }
1880     if(_stream->url.user!=NULL&&_stream->url.pass!=NULL){
1881       ret|=op_sb_append_basic_auth_header(&_stream->request,
1882        "Authorization",_stream->url.user,_stream->url.pass);
1883     }
1884     /*Always send a Referer [sic] header.
1885       It's common to refuse to serve a resource unless one is present.
1886       We just use the relative "/" URI to suggest we came from the same domain,
1887        as this is the most common check.
1888       This might violate RFC 2616's mandate that the field "MUST NOT be sent if
1889        the Request-URI was obtained from a source that does not have its own
1890        URI, such as input from the user keyboard," but we don't really have any
1891        way to know.*/
1892     /*TODO: Should we update this on redirects?*/
1893     ret|=op_sb_append(&_stream->request,"Referer: /\r\n",12);
1894     /*Always send a Range request header to find out if we're seekable.
1895       This requires an HTTP/1.1 server to succeed, but we'll still get what we
1896        want with an HTTP/1.0 server that ignores this request header.*/
1897     ret|=op_sb_append(&_stream->request,"Range: bytes=0-\r\n",17);
1898     /*Remember where this is so we can append offsets to it later.*/
1899     _stream->request_tail=_stream->request.nbuf-4;
1900     ret|=op_sb_append(&_stream->request,"\r\n",2);
1901     if(OP_UNLIKELY(ret<0))return ret;
1902     ret=op_http_conn_write_fully(_stream->conns+0,
1903      _stream->request.buf,_stream->request.nbuf);
1904     if(OP_UNLIKELY(ret<0))return ret;
1905     ret=op_http_conn_read_response(_stream->conns+0,&_stream->response);
1906     if(OP_UNLIKELY(ret<0))return ret;
1907     ret=ftime(&end_time);
1908     OP_ASSERT(!ret);
1909     next=op_http_parse_status_line(&v1_1_compat,&status_code,
1910      _stream->response.buf);
1911     if(OP_UNLIKELY(next==NULL))return OP_FALSE;
1912     if(status_code[0]=='2'){
1913       opus_int64 content_length;
1914       opus_int64 range_length;
1915       int        pipeline;
1916       /*We only understand 20x codes.*/
1917       if(status_code[1]!='0')return OP_FALSE;
1918       content_length=-1;
1919       range_length=-1;
1920       /*Pipelining is disabled by default.*/
1921       pipeline=0;
1922       for(;;){
1923         char *header;
1924         char *cdr;
1925         ret=op_http_get_next_header(&header,&cdr,&next);
1926         if(OP_UNLIKELY(ret<0))return ret;
1927         if(header==NULL)break;
1928         if(strcmp(header,"content-length")==0){
1929           /*Two Content-Length headers?*/
1930           if(OP_UNLIKELY(content_length>=0))return OP_FALSE;
1931           content_length=op_http_parse_content_length(cdr);
1932           if(OP_UNLIKELY(content_length<0))return (int)content_length;
1933           /*Make sure the Content-Length and Content-Range headers match.*/
1934           if(range_length>=0&&OP_UNLIKELY(content_length!=range_length)){
1935             return OP_FALSE;
1936           }
1937         }
1938         else if(strcmp(header,"content-range")==0){
1939           opus_int64 range_first;
1940           opus_int64 range_last;
1941           /*Two Content-Range headers?*/
1942           if(OP_UNLIKELY(range_length>=0))return OP_FALSE;
1943           ret=op_http_parse_content_range(&range_first,&range_last,
1944            &range_length,cdr);
1945           if(OP_UNLIKELY(ret<0))return ret;
1946           /*"A response with satus code 206 (Partial Content) MUST NOTE
1947              include a Content-Range field with a byte-range-resp-spec of
1948              '*'."*/
1949           if(status_code[2]=='6'
1950            &&(OP_UNLIKELY(range_first<0)||OP_UNLIKELY(range_last<0))){
1951             return OP_FALSE;
1952           }
1953           /*We asked for the entire resource.*/
1954           if(range_length>=0){
1955             /*Quit if we didn't get it.*/
1956             if(range_last>=0&&OP_UNLIKELY(range_last!=range_length-1)){
1957               return OP_FALSE;
1958             }
1959           }
1960           /*If there was no length, use the end of the range.*/
1961           else if(range_last>=0)range_length=range_last+1;
1962           /*Make sure the Content-Length and Content-Range headers match.*/
1963           if(content_length>=0&&OP_UNLIKELY(content_length!=range_length)){
1964             return OP_FALSE;
1965           }
1966         }
1967         else if(strcmp(header,"connection")==0){
1968           /*According to RFC 2616, if an HTTP/1.1 application does not support
1969              pipelining, it "MUST include the 'close' connection option in
1970              every message."
1971             Therefore, if we receive one in the initial response, disable
1972              pipelining entirely.
1973             The server still might support it (e.g., we might just have hit the
1974              request limit for a temporary child process), but if it doesn't
1975              and we assume it does, every time we cross a chunk boundary we'll
1976              error out and reconnect, adding lots of latency.*/
1977           ret=op_http_parse_connection(cdr);
1978           if(OP_UNLIKELY(ret<0))return ret;
1979           pipeline-=ret;
1980         }
1981         else if(strcmp(header,"server")){
1982           /*If we got a Server response header, and it wasn't from a known-bad
1983              server, enable pipelining, as long as it's at least HTTP/1.1.
1984             According to RFC 2145, the server is supposed to respond with the
1985              highest minor version number it supports unless it is known or
1986              suspected that we incorrectly implement the HTTP specification.
1987             So it should send back at least HTTP/1.1, despite our HTTP/1.0
1988              request.*/
1989           pipeline+=v1_1_compat&&op_http_allow_pipelining(cdr);
1990         }
1991       }
1992       switch(status_code[2]){
1993         /*200 OK*/
1994         case '0':break;
1995         /*203 Non-Authoritative Information*/
1996         case '3':break;
1997         /*204 No Content*/
1998         case '4':{
1999           if(content_length>=0&&OP_UNLIKELY(content_length!=0)){
2000             return OP_FALSE;
2001           }
2002         }break;
2003         /*206 Partial Content*/
2004         case '6':{
2005           /*No Content-Range header.*/
2006           if(OP_UNLIKELY(range_length<0))return OP_FALSE;
2007           content_length=range_length;
2008           /*The server supports range requests for this resource.
2009             We can seek.*/
2010           _stream->seekable=1;
2011         }break;
2012         /*201 Created: the response "SHOULD include an entity containing a list
2013            of resource characteristics and location(s)," but not an Opus file.
2014           202 Accepted: the response "SHOULD include an indication of request's
2015            current status and either a pointer to a status monitor or some
2016            estimate of when the user can expect the request to be fulfilled,"
2017            but not an Opus file.
2018           205 Reset Content: this "MUST NOT include an entity," meaning no Opus
2019            file.
2020           207...209 are not yet defined, so we don't know how to handle them.*/
2021         default:return OP_FALSE;
2022       }
2023       _stream->content_length=content_length;
2024       _stream->pipeline=pipeline>0;
2025       /*Pipelining requires HTTP/1.1 persistent connections.*/
2026       if(pipeline)_stream->request.buf[minor_version_pos]='1';
2027       _stream->conns[0].pos=0;
2028       _stream->conns[0].end_pos=_stream->seekable?content_length:-1;
2029       _stream->conns[0].chunk_size=-1;
2030       _stream->cur_conni=0;
2031       _stream->connect_rate=op_time_diff_ms(&end_time,&start_time);
2032       _stream->connect_rate=OP_MAX(_stream->connect_rate,1);
2033       /*The URL has been successfully opened.*/
2034       return 0;
2035     }
2036     /*Shouldn't get 1xx; 4xx and 5xx are both failures (and we don't retry).
2037       Everything else is undefined.*/
2038     else if(status_code[0]!='3')return OP_FALSE;
2039     /*We have some form of redirect request.*/
2040     /*We only understand 30x codes.*/
2041     if(status_code[1]!='0')return OP_FALSE;
2042     switch(status_code[2]){
2043       /*300 Multiple Choices: "If the server has a preferred choice of
2044          representation, it SHOULD include the specific URI for that
2045          representation in the Location field," otherwise we'll fail.*/
2046       case '0':
2047       /*301 Moved Permanently*/
2048       case '1':
2049       /*302 Found*/
2050       case '2':
2051       /*307 Temporary Redirect*/
2052       case '7':break;
2053       /*305 Use Proxy: "The Location field gives the URI of the proxy."
2054         TODO: This shouldn't actually be that hard to do.*/
2055       case '5':return OP_EIMPL;
2056       /*303 See Other: "The new URI is not a substitute reference for the
2057          originally requested resource."
2058         304 Not Modified: "The 304 response MUST NOT contain a message-body."
2059         306 (Unused)
2060         308...309 are not yet defined, so we don't know how to handle them.*/
2061       default:return OP_FALSE;
2062     }
2063     _url=NULL;
2064     for(;;){
2065       char *header;
2066       char *cdr;
2067       ret=op_http_get_next_header(&header,&cdr,&next);
2068       if(OP_UNLIKELY(ret<0))return ret;
2069       if(header==NULL)break;
2070       if(strcmp(header,"location")==0&&OP_LIKELY(_url==NULL))_url=cdr;
2071     }
2072     if(OP_UNLIKELY(_url==NULL))return OP_FALSE;
2073     /*Don't free last_host if it came from the last URL.*/
2074     if(last_host!=_proxy_host)_stream->url.host=NULL;
2075     op_parsed_url_clear(&_stream->url);
2076     ret=op_parse_url(&_stream->url,_url);
2077     if(OP_UNLIKELY(ret<0)){
2078       if(ret==OP_EINVAL)ret=OP_FALSE;
2079       if(last_host!=_proxy_host)_ogg_free((void *)last_host);
2080       return ret;
2081     }
2082     op_http_conn_close(_stream,_stream->conns+0,&_stream->lru_head,1);
2083   }
2084   /*Redirection limit reached.*/
2085   return OP_FALSE;
2086 }
2087
2088 static int op_http_conn_send_request(OpusHTTPStream *_stream,
2089  OpusHTTPConn *_conn,opus_int64 _pos,opus_int32 _chunk_size,
2090  int _try_not_to_block){
2091   opus_int64 next_end;
2092   int        ret;
2093   /*We shouldn't have another request outstanding.*/
2094   OP_ASSERT(_conn->next_pos<0);
2095   /*Build the request to send.*/
2096   OP_ASSERT(_stream->request.nbuf>=_stream->request_tail);
2097   _stream->request.nbuf=_stream->request_tail;
2098   ret=op_sb_append_nonnegative_int64(&_stream->request,_pos);
2099   ret|=op_sb_append(&_stream->request,"-",1);
2100   if(_chunk_size>0&&_pos<=OP_INT64_MAX-_chunk_size
2101    &&_pos+_chunk_size<_stream->content_length){
2102     /*We shouldn't be pipelining requests with non-HTTP/1.1 servers.*/
2103     OP_ASSERT(_stream->pipeline);
2104     next_end=_pos+_chunk_size;
2105     ret|=op_sb_append_nonnegative_int64(&_stream->request,next_end-1);
2106     /*Use a larger chunk size for our next request.*/
2107     _chunk_size<<=1;
2108     /*But after a while, just request the rest of the resource.*/
2109     if(_chunk_size>OP_PIPELINE_CHUNK_SIZE_MAX)_chunk_size=-1;
2110   }
2111   else{
2112     next_end=-1;
2113     _chunk_size=-1;
2114   }
2115   ret|=op_sb_append(&_stream->request,"\r\n\r\n",4);
2116   if(OP_UNLIKELY(ret<0))return ret;
2117   /*If we don't want to block, check to see if there's enough space in the send
2118      queue.
2119     There's still a chance we might block, even if there is enough space, but
2120      it's a much slimmer one.
2121     Blocking at all is pretty unlikely, as we won't have any requests queued
2122      when _try_not_to_block is set, so if FIONSPACE isn't available (e.g., on
2123      Linux), just skip the test.*/
2124   if(_try_not_to_block){
2125 # if defined(FIONSPACE)
2126     int available;
2127     ret=ioctl(_conn->fd,FIONSPACE,&available);
2128     if(ret<0||available<_stream->request.nbuf)return 1;
2129 # endif
2130   }
2131   ret=op_http_conn_write_fully(_conn,
2132    _stream->request.buf,_stream->request.nbuf);
2133   if(OP_UNLIKELY(ret<0))return ret;
2134   _conn->next_pos=_pos;
2135   _conn->next_end=next_end;
2136   /*Save the chunk size to use for the next request.*/
2137   _conn->chunk_size=_chunk_size;
2138   _conn->nrequests_left--;
2139   return ret;
2140 }
2141
2142 /*Handles the response to all requests after the first one.
2143   Return: 1 if the connection was closed or timed out, 0 on success, or a
2144            negative value on any other error.*/
2145 static int op_http_conn_handle_response(OpusHTTPStream *_stream,
2146  OpusHTTPConn *_conn){
2147   char       *next;
2148   char       *status_code;
2149   opus_int64  range_length;
2150   opus_int64  next_pos;
2151   opus_int64  next_end;
2152   int         ret;
2153   ret=op_http_conn_read_response(_conn,&_stream->response);
2154   /*If the server just closed the connection on us, we may have just hit a
2155      connection re-use limit, so we might want to retry.*/
2156   if(OP_UNLIKELY(ret<0))return ret==OP_EREAD?1:ret;
2157   next=op_http_parse_status_line(NULL,&status_code,_stream->response.buf);
2158   if(OP_UNLIKELY(next==NULL))return OP_FALSE;
2159   /*We _need_ a 206 Partial Content response.
2160     Nothing else will do.*/
2161   if(strncmp(status_code,"206",3)!=0){
2162     /*But on a 408 Request Timeout, we might want to re-try.*/
2163     return strncmp(status_code,"408",3)==0?1:OP_FALSE;
2164   }
2165   next_pos=_conn->next_pos;
2166   next_end=_conn->next_end;
2167   range_length=-1;
2168   for(;;){
2169     char *header;
2170     char *cdr;
2171     ret=op_http_get_next_header(&header,&cdr,&next);
2172     if(OP_UNLIKELY(ret<0))return ret;
2173     if(header==NULL)break;
2174     if(strcmp(header,"content-range")==0){
2175       opus_int64 range_first;
2176       opus_int64 range_last;
2177       /*Two Content-Range headers?*/
2178       if(OP_UNLIKELY(range_length>=0))return OP_FALSE;
2179       ret=op_http_parse_content_range(&range_first,&range_last,
2180        &range_length,cdr);
2181       if(OP_UNLIKELY(ret<0))return ret;
2182       /*"A response with satus code 206 (Partial Content) MUST NOT
2183          include a Content-Range field with a byte-range-resp-spec of
2184          '*'."*/
2185       if(OP_UNLIKELY(range_first<0)||OP_UNLIKELY(range_last<0))return OP_FALSE;
2186       /*We also don't want range_last to overflow.*/
2187       if(OP_UNLIKELY(range_last>=OP_INT64_MAX))return OP_FALSE;
2188       range_last++;
2189       /*Quit if we didn't get the offset we asked for.*/
2190       if(range_first!=next_pos)return OP_FALSE;
2191       if(next_end<0){
2192         /*We asked for the rest of the resource.*/
2193         if(range_length>=0){
2194           /*Quit if we didn't get it.*/
2195           if(OP_UNLIKELY(range_last!=range_length))return OP_FALSE;
2196         }
2197         /*If there was no length, use the end of the range.*/
2198         else range_length=range_last;
2199         next_end=range_last;
2200       }
2201       else{
2202         if(range_last!=next_end)return OP_FALSE;
2203         /*If there was no length, use the larger of the content length or the
2204            end of this chunk.*/
2205         if(range_length<0){
2206           range_length=OP_MAX(range_last,_stream->content_length);
2207         }
2208       }
2209     }
2210     else if(strcmp(header,"content-length")==0){
2211       opus_int64 content_length;
2212       /*Validate the Content-Length header, if present, against the request we
2213          made.*/
2214       content_length=op_http_parse_content_length(cdr);
2215       if(OP_UNLIKELY(content_length<0))return (int)content_length;
2216       if(next_end<0){
2217         /*If we haven't seen the Content-Range header yet and we asked for the
2218             rest of the resource, set next_end, so we can make sure they match
2219             when we do find the Content-Range header.*/
2220         if(OP_UNLIKELY(next_pos>OP_INT64_MAX-content_length))return OP_FALSE;
2221         next_end=next_pos+content_length;
2222       }
2223       /*Otherwise, make sure they match now.*/
2224       else if(OP_UNLIKELY(next_end-next_pos!=content_length))return OP_FALSE;
2225     }
2226     else if(strcmp(header,"connection")==0){
2227       ret=op_http_parse_connection(cdr);
2228       if(OP_UNLIKELY(ret<0))return ret;
2229       /*If the server told us it was going to close the connection, don't make
2230          any more requests.*/
2231       if(OP_UNLIKELY(ret>0))_conn->nrequests_left=0;
2232     }
2233   }
2234   /*No Content-Range header.*/
2235   if(OP_UNLIKELY(range_length<0))return OP_FALSE;
2236   /*Update the content_length if necessary.*/
2237   _stream->content_length=range_length;
2238   _conn->pos=next_pos;
2239   _conn->end_pos=next_end;
2240   _conn->next_pos=-1;
2241   return 0;
2242 }
2243
2244 /*Open a new connection that will start reading at byte offset _pos.
2245   _pos:        The byte offset to start readiny from.
2246   _chunk_size: The number of bytes to ask for in the initial request, or -1 to
2247                 request the rest of the resource.
2248                This may be more bytes than remain, in which case it will be
2249                 converted into a request for the rest.*/
2250 static int op_http_conn_open_pos(OpusHTTPStream *_stream,
2251  OpusHTTPConn *_conn,opus_int64 _pos,opus_int32 _chunk_size){
2252   struct timeb  start_time;
2253   struct timeb  end_time;
2254   opus_int32    connect_rate;
2255   opus_int32    connect_time;
2256   int           ret;
2257   ret=op_http_connect(_stream,_conn,&_stream->addr_info,&start_time);
2258   if(OP_UNLIKELY(ret<0))return ret;
2259   ret=op_http_conn_send_request(_stream,_conn,_pos,_chunk_size,0);
2260   if(OP_UNLIKELY(ret<0))return ret;
2261   ret=op_http_conn_handle_response(_stream,_conn);
2262   if(OP_UNLIKELY(ret!=0))return OP_FALSE;
2263   ret=ftime(&end_time);
2264   OP_ASSERT(!ret);
2265   _stream->cur_conni=_conn-_stream->conns;
2266   OP_ASSERT(_stream->cur_conni>=0&&_stream->cur_conni<OP_NCONNS_MAX);
2267   /*The connection has been successfully opened.
2268     Update the connection time estimate.*/
2269   connect_time=op_time_diff_ms(&end_time,&start_time);
2270   connect_rate=_stream->connect_rate;
2271   connect_rate+=OP_MAX(connect_time,1)-connect_rate+8>>4;
2272   _stream->connect_rate=connect_rate;
2273   return 0;
2274 }
2275
2276 /*Read data from the current response body.
2277   If we're pipelining and we get close to the end of this response, queue
2278    another request.
2279   If we've reached the end of this response body, parse the next response and
2280    keep going.
2281   [out] _buf: Returns the data read.
2282   _buf_size:  The size of the buffer.
2283   Return: A positive number of bytes read on success.
2284           0:        The connection was closed.
2285           OP_EREAD: There was a fatal read error.*/
2286 static int op_http_conn_read_body(OpusHTTPStream *_stream,
2287  OpusHTTPConn *_conn,unsigned char *_buf,int _buf_size){
2288   opus_int64 pos;
2289   opus_int64 end_pos;
2290   opus_int64 next_pos;
2291   opus_int64 content_length;
2292   int        nread;
2293   int        pipeline;
2294   int        ret;
2295   /*Currently this function can only be called on the LRU head.
2296     Otherwise, we'd need a _pnext pointer if we needed to close the connection,
2297      and re-opening it would re-organize the lists.*/
2298   OP_ASSERT(_stream->lru_head==_conn);
2299   /*We should have filterd out empty reads by this point.*/
2300   OP_ASSERT(_buf_size>0);
2301   pos=_conn->pos;
2302   end_pos=_conn->end_pos;
2303   next_pos=_conn->next_pos;
2304   pipeline=_stream->pipeline;
2305   content_length=_stream->content_length;
2306   if(end_pos>=0){
2307     /*Have we reached the end of the current response body?*/
2308     if(pos>=end_pos){
2309       OP_ASSERT(content_length>=0);
2310       /*If this was the end of the stream, we're done.
2311         Also return early if a non-blocking read was requested (regardless of
2312          whether we might be able to parse the next response without
2313          blocking).*/
2314       if(content_length<=end_pos)return 0;
2315       /*Otherwise, start on the next response.*/
2316       if(next_pos<0){
2317         /*We haven't issued another request yet.*/
2318         if(!pipeline||_conn->nrequests_left<=0){
2319           /*There are two ways to get here: either the server told us it was
2320              going to close the connection after the last request, or we
2321              thought we were reading the whole resource, but it grew while we
2322              were reading it.
2323             The only way the latter could have happened is if content_length
2324              changed while seeking.
2325             Open a new request to read the rest.*/
2326           OP_ASSERT(_stream->seekable);
2327           /*Try to open a new connection to read another chunk.*/
2328           op_http_conn_close(_stream,_conn,&_stream->lru_head,1);
2329           /*If we're not pipelining, we should be requesting the rest.*/
2330           OP_ASSERT(pipeline||_conn->chunk_size==-1);
2331           ret=op_http_conn_open_pos(_stream,_conn,end_pos,_conn->chunk_size);
2332           if(OP_UNLIKELY(ret<0))return OP_EREAD;
2333         }
2334         else{
2335           /*Issue the request now (better late than never).*/
2336           ret=op_http_conn_send_request(_stream,_conn,pos,_conn->chunk_size,0);
2337           if(OP_UNLIKELY(ret<0))return OP_EREAD;
2338           next_pos=_conn->next_pos;
2339           OP_ASSERT(next_pos>=0);
2340         }
2341       }
2342       if(next_pos>=0){
2343         /*We shouldn't be trying to read past the current request body if we're
2344            seeking somewhere else.*/
2345         OP_ASSERT(next_pos==end_pos);
2346         ret=op_http_conn_handle_response(_stream,_conn);
2347         if(OP_UNLIKELY(ret<0))return OP_EREAD;
2348         if(OP_UNLIKELY(ret>0)&&pipeline){
2349           opus_int64 next_end;
2350           next_end=_conn->next_end;
2351           /*Our request timed out or the server closed the connection.
2352             Try re-connecting.*/
2353           op_http_conn_close(_stream,_conn,&_stream->lru_head,1);
2354           /*Unless there's a bug, we should be able to convert
2355              (next_pos,next_end) into valid (_pos,_chunk_size) parameters.*/
2356           OP_ASSERT(next_end<0
2357            ||next_end-next_pos>=0&&next_end-next_pos<=0x7FFFFFFF);
2358           ret=op_http_conn_open_pos(_stream,_conn,next_pos,
2359            next_end<0?-1:(opus_int32)(next_end-next_pos));
2360           if(OP_UNLIKELY(ret<0))return OP_EREAD;
2361         }
2362         else if(OP_UNLIKELY(ret!=0))return OP_EREAD;
2363       }
2364       pos=_conn->pos;
2365       end_pos=_conn->end_pos;
2366       content_length=_stream->content_length;
2367     }
2368     OP_ASSERT(end_pos>pos);
2369     _buf_size=OP_MIN(_buf_size,end_pos-pos);
2370   }
2371   nread=op_http_conn_read(_conn,_buf,_buf_size,1);
2372   if(OP_UNLIKELY(nread<0))return nread;
2373   pos+=nread;
2374   _conn->pos=pos;
2375   OP_ASSERT(end_pos<0||content_length>=0);
2376   /*TODO: If nrequests_left<=0, we can't make a new request, and there will be
2377      a big pause after we hit the end of the chunk while we open a new
2378      connection.
2379     It would be nice to be able to start that process now, but we have no way
2380      to do it in the background without blocking (even if we could start it, we
2381      have no guarantee the application will return control to us in a
2382      sufficiently timely manner to allow us to complete it, and this is
2383      uncommon enough that it's not worth using threads just for this).*/
2384   if(end_pos>=0&&end_pos<content_length&&next_pos<0
2385    &&pipeline&&OP_LIKELY(_conn->nrequests_left>0)){
2386     opus_int64 request_thresh;
2387     opus_int32 chunk_size;
2388     /*Are we getting close to the end of the current response body?
2389       If so, we should request more data.*/
2390     request_thresh=_stream->connect_rate*_conn->read_rate>>12;
2391     /*But don't commit ourselves too quickly.*/
2392     chunk_size=_conn->chunk_size;
2393     if(chunk_size>=0)request_thresh=OP_MIN(chunk_size>>2,request_thresh);
2394     if(end_pos-pos<=request_thresh){
2395       ret=op_http_conn_send_request(_stream,_conn,end_pos,_conn->chunk_size,1);
2396       if(OP_UNLIKELY(ret<0))return OP_EREAD;
2397     }
2398   }
2399   return nread;
2400 }
2401
2402 static int op_http_stream_read(void *_stream,
2403  unsigned char *_ptr,int _buf_size){
2404   OpusHTTPStream *stream;
2405   ptrdiff_t       nread;
2406   opus_int64      size;
2407   opus_int64      pos;
2408   int             ci;
2409   stream=(OpusHTTPStream *)_stream;
2410   /*Check for an empty read.*/
2411   if(_buf_size<=0)return 0;
2412   ci=stream->cur_conni;
2413   /*No current connection => EOF.*/
2414   if(ci<0)return 0;
2415   pos=stream->conns[ci].pos;
2416   size=stream->content_length;
2417   /*Check for EOF.*/
2418   if(size>=0){
2419     if(pos>=size)return 0;
2420     /*Check for a short read.*/
2421     if(_buf_size>size-pos)_buf_size=(int)(size-pos);
2422   }
2423   nread=op_http_conn_read_body(stream,stream->conns+ci,_ptr,_buf_size);
2424   if(OP_UNLIKELY(nread<=0)){
2425     /*We hit an error or EOF.
2426       Either way, we're done with this connection.*/
2427     op_http_conn_close(stream,stream->conns+ci,&stream->lru_head,1);
2428     stream->cur_conni=-1;
2429     stream->pos=pos;
2430   }
2431   return nread;
2432 }
2433
2434 /*Discard data until we reach the _target position.
2435   _just_read_ahead: Whether or not this is a plain fast-forward.
2436                     If 0, we need to issue a new request for a chunk at _target
2437                      and discard all the data from our current request(s).
2438                     Otherwise, we should be able to reach _target without
2439                      issuing any new requests.
2440   _target:          The stream position to which to read ahead.*/
2441 static int op_http_conn_read_ahead(OpusHTTPStream *_stream,
2442  OpusHTTPConn *_conn,int _just_read_ahead,opus_int64 _target){
2443   static unsigned char dummy_buf[OP_READAHEAD_CHUNK_SIZE];
2444   opus_int64 pos;
2445   opus_int64 end_pos;
2446   opus_int64 next_pos;
2447   opus_int64 next_end;
2448   ptrdiff_t  nread;
2449   int        ret;
2450   pos=_conn->pos;
2451   end_pos=_conn->end_pos;
2452   next_pos=_conn->next_pos;
2453   next_end=_conn->next_end;
2454   if(!_just_read_ahead){
2455     /*We need to issue a new pipelined request.
2456       This is the only case where we allow more than one outstanding request
2457        at a time, so we need to reset next_pos (we'll restore it below if we
2458        did have an outstanding request).*/
2459     OP_ASSERT(_stream->pipeline);
2460     _conn->next_pos=-1;
2461     ret=op_http_conn_send_request(_stream,_conn,_target,
2462      OP_PIPELINE_CHUNK_SIZE,0);
2463     if(OP_UNLIKELY(ret<0))return ret;
2464   }
2465   /*We can reach the target position by reading forward in the current chunk.*/
2466   if(_just_read_ahead&&(end_pos<0||_target<end_pos))end_pos=_target;
2467   else if(next_pos>=0){
2468     opus_int64 next_next_pos;
2469     opus_int64 next_next_end;
2470     /*We already have a request outstanding.
2471       Finish off the current chunk.*/
2472     while(pos<end_pos){
2473       nread=op_http_conn_read(_conn,dummy_buf,
2474        (int)OP_MIN(end_pos-pos,OP_READAHEAD_CHUNK_SIZE),1);
2475       /*We failed to read ahead.*/
2476       if(nread<=0)return OP_FALSE;
2477       pos+=nread;
2478     }
2479     OP_ASSERT(pos==end_pos);
2480     if(_just_read_ahead){
2481       next_next_pos=next_next_end=-1;
2482       end_pos=_target;
2483     }
2484     else{
2485       OP_ASSERT(_conn->next_pos==_target);
2486       next_next_pos=_target;
2487       next_next_end=_conn->next_end;
2488       _conn->next_pos=next_pos;
2489       _conn->next_end=next_end;
2490       end_pos=next_end;
2491     }
2492     ret=op_http_conn_handle_response(_stream,_conn);
2493     if(OP_UNLIKELY(ret!=0))return OP_FALSE;
2494     _conn->next_pos=next_next_pos;
2495     _conn->next_end=next_next_end;
2496   }
2497   while(pos<end_pos){
2498     nread=op_http_conn_read(_conn,dummy_buf,
2499      (int)OP_MIN(end_pos-pos,OP_READAHEAD_CHUNK_SIZE),1);
2500     /*We failed to read ahead.*/
2501     if(nread<=0)return OP_FALSE;
2502     pos+=nread;
2503   }
2504   OP_ASSERT(pos==end_pos);
2505   if(!_just_read_ahead){
2506     ret=op_http_conn_handle_response(_stream,_conn);
2507     if(OP_UNLIKELY(ret!=0))return OP_FALSE;
2508   }
2509   else _conn->pos=end_pos;
2510   OP_ASSERT(_conn->pos==_target);
2511   return 0;
2512 }
2513
2514 static int op_http_stream_seek(void *_stream,opus_int64 _offset,int _whence){
2515   struct timeb     seek_time;
2516   OpusHTTPStream  *stream;
2517   OpusHTTPConn    *conn;
2518   OpusHTTPConn   **pnext;
2519   OpusHTTPConn    *close_conn;
2520   OpusHTTPConn   **close_pnext;
2521   opus_int64       content_length;
2522   opus_int64       pos;
2523   int              pipeline;
2524   int              ci;
2525   int              ret;
2526   stream=(OpusHTTPStream *)_stream;
2527   if(!stream->seekable)return -1;
2528   content_length=stream->content_length;
2529   /*If we're seekable, we should have gotten a Content-Length.*/
2530   OP_ASSERT(content_length>=0);
2531   ci=stream->cur_conni;
2532   pos=ci<0?content_length:stream->conns[ci].pos;
2533   switch(_whence){
2534     case SEEK_SET:{
2535       /*Check for overflow:*/
2536       if(_offset<0)return -1;
2537       pos=_offset;
2538     }break;
2539     case SEEK_CUR:{
2540       /*Check for overflow:*/
2541       if(_offset<-pos||_offset>OP_INT64_MAX-pos)return -1;
2542       pos+=_offset;
2543     }break;
2544     case SEEK_END:{
2545       /*Check for overflow:*/
2546       if(_offset>content_length||_offset<content_length-OP_INT64_MAX)return -1;
2547       pos=content_length-_offset;
2548     }break;
2549     default:return -1;
2550   }
2551   /*Mark when we deactivated the active connection.*/
2552   if(ci>=0){
2553     op_http_conn_read_rate_update(stream->conns+ci);
2554     *&seek_time=*&stream->conns[ci].read_time;
2555   }
2556   else{
2557     ret=ftime(&seek_time);
2558     OP_ASSERT(!ret);
2559   }
2560   /*If we seeked past the end of the stream, just disable the active
2561      connection.*/
2562   if(pos>=content_length){
2563     stream->cur_conni=-1;
2564     stream->pos=pos;
2565     return 0;
2566   }
2567   close_pnext=NULL;
2568   close_conn=NULL;
2569   pnext=&stream->lru_head;
2570   conn=stream->lru_head;
2571   pipeline=stream->pipeline;
2572   while(conn!=NULL){
2573     opus_int64 conn_pos;
2574     opus_int64 end_pos;
2575     opus_int64 read_ahead_thresh;
2576     int        available;
2577     int        just_read_ahead;
2578     /*If this connection has been dormant too long or has made too many
2579        requests, close it.
2580       This is to prevent us from hitting server limits/firewall timeouts.*/
2581     if(op_time_diff_ms(&seek_time,&conn->read_time)>
2582      OP_CONNECTION_IDLE_TIMEOUT_MS
2583      ||conn->nrequests_left<OP_PIPELINE_MIN_REQUESTS){
2584       op_http_conn_close(stream,conn,pnext,1);
2585       conn=*pnext;
2586       continue;
2587     }
2588     /*Dividing by 2048 instead of 1000 scales this by nearly 1/2, biasing away
2589        from connection re-use (and roughly compensating for the lag required to
2590        reopen the TCP window of a connection that's been idle).
2591       There's no overflow checking here, because it's vanishingly unlikely, and
2592        all it would do is cause us to make poor decisions.*/
2593     read_ahead_thresh=OP_MAX(OP_READAHEAD_THRESH_MIN,
2594      stream->connect_rate*conn->read_rate>>11);
2595     available=op_http_conn_estimate_available(conn);
2596     conn_pos=conn->pos;
2597     end_pos=conn->end_pos;
2598     if(conn->next_pos>=0){
2599       OP_ASSERT(end_pos>=0);
2600       OP_ASSERT(conn->next_pos==end_pos);
2601       end_pos=conn->next_end;
2602     }
2603     OP_ASSERT(end_pos<0||conn_pos<=end_pos);
2604     /*Can we quickly read ahead without issuing a new request?*/
2605     just_read_ahead=conn_pos<=pos&&pos-conn_pos-available<=read_ahead_thresh
2606      &&(end_pos<0||pos<end_pos);
2607     if(just_read_ahead||pipeline&&end_pos>=0
2608      &&end_pos-conn_pos-available<=read_ahead_thresh){
2609       /*Found a suitable connection to re-use.
2610         We always attempt to re-use the first suitable connection we find, even
2611          if another one might require less read-ahead, under the assumption
2612          more recently used connetions have TCP windows that are open wider.
2613         This seems to give a slight performance boost over picking the one with
2614          the shortest estimated read-ahead time.*/
2615       ret=op_http_conn_read_ahead(stream,conn,just_read_ahead,pos);
2616       if(OP_UNLIKELY(ret<0)){
2617         /*The connection might have become stale, so close it and keep going.*/
2618         op_http_conn_close(stream,conn,pnext,1);
2619         conn=*pnext;
2620         continue;
2621       }
2622       /*Sucessfully resurrected this connection.*/
2623       *pnext=conn->next;
2624       conn->next=stream->lru_head;
2625       stream->lru_head=conn;
2626       stream->cur_conni=conn-stream->conns;
2627       return 0;
2628     }
2629     close_pnext=pnext;
2630     close_conn=conn;
2631     pnext=&conn->next;
2632     conn=conn->next;
2633   }
2634   /*No suitable connections.
2635     Open a new one.*/
2636   if(stream->free_head==NULL){
2637     /*All connections in use.
2638       Expire one of them (we should have already picked which one when scanning
2639        the list).*/
2640     OP_ASSERT(close_conn!=NULL);
2641     OP_ASSERT(close_pnext!=NULL);
2642     op_http_conn_close(stream,close_conn,close_pnext,1);
2643   }
2644   OP_ASSERT(stream->free_head!=NULL);
2645   conn=stream->free_head;
2646   /*If we can pipeline, only request a chunk of data.
2647     If we're seeking now, there's a good chance we will want to seek again
2648      soon, and this avoids committing this connection to reading the rest of
2649      the stream.
2650     Particularly with SSL or proxies, issuing a new request on the same
2651      connection can be substantially faster than opening a new one.
2652     This also limits the amount of data the server will blast at us on this
2653      connection if we later seek elsewhere and start reading from a different
2654      connection.*/
2655   ret=op_http_conn_open_pos(stream,conn,pos,
2656    pipeline?OP_PIPELINE_CHUNK_SIZE:-1);
2657   if(OP_UNLIKELY(ret<0)){
2658     op_http_conn_close(stream,conn,&stream->lru_head,1);
2659     return -1;
2660   }
2661   return 0;
2662 }
2663
2664 static opus_int64 op_http_stream_tell(void *_stream){
2665   OpusHTTPStream *stream;
2666   int             ci;
2667   stream=(OpusHTTPStream *)_stream;
2668   ci=stream->cur_conni;
2669   return ci<0?stream->pos:stream->conns[ci].pos;
2670 }
2671
2672 static int op_http_stream_close(void *_stream){
2673   OpusHTTPStream *stream;
2674   stream=(OpusHTTPStream *)_stream;
2675   if(OP_LIKELY(stream!=NULL)){
2676     op_http_stream_clear(stream);
2677     _ogg_free(stream);
2678   }
2679   return 0;
2680 }
2681
2682 static const OpusFileCallbacks OP_HTTP_CALLBACKS={
2683   op_http_stream_read,
2684   op_http_stream_seek,
2685   op_http_stream_tell,
2686   op_http_stream_close
2687 };
2688 #endif
2689
2690 /*The actual URL stream creation function.
2691   This one isn't extensible like the application-level interface, but because
2692    it isn't public, we're free to change it in the future.*/
2693 static void *op_url_stream_create_impl(OpusFileCallbacks *_cb,const char *_url,
2694  int _skip_certificate_check,const char *_proxy_host,unsigned _proxy_port,
2695  const char *_proxy_user,const char *_proxy_pass){
2696   const char *path;
2697   /*Check to see if this is a valid file: URL.*/
2698   path=op_parse_file_url(_url);
2699   if(path!=NULL){
2700     char *unescaped_path;
2701     void *ret;
2702     unescaped_path=op_string_dup(path);
2703     if(OP_UNLIKELY(unescaped_path==NULL))return NULL;
2704     ret=op_fopen(_cb,op_unescape_url_component(unescaped_path),"rb");
2705     _ogg_free(unescaped_path);
2706     return ret;
2707   }
2708 #if defined(OP_ENABLE_HTTP)
2709   /*If not, try http/https.*/
2710   else{
2711     OpusHTTPStream *stream;
2712     int             ret;
2713     stream=(OpusHTTPStream *)_ogg_malloc(sizeof(*stream));
2714     if(OP_UNLIKELY(stream==NULL))return NULL;
2715     op_http_stream_init(stream);
2716     ret=op_http_stream_open(stream,_url,_skip_certificate_check,
2717      _proxy_host,_proxy_port,_proxy_user,_proxy_pass);
2718     if(OP_UNLIKELY(ret<0)){
2719       op_http_stream_clear(stream);
2720       _ogg_free(stream);
2721       return NULL;
2722     }
2723     *_cb=*&OP_HTTP_CALLBACKS;
2724     return stream;
2725   }
2726 #else
2727   (void)_skip_certificate_check;
2728   (void)_proxy_host;
2729   (void)_proxy_port;
2730   (void)_proxy_user;
2731   (void)_proxy_pass;
2732   return NULL;
2733 #endif
2734 }
2735
2736 void *op_url_stream_vcreate(OpusFileCallbacks *_cb,
2737  const char *_url,va_list _ap){
2738   int         skip_certificate_check;
2739   const char *proxy_host;
2740   opus_int32  proxy_port;
2741   const char *proxy_user;
2742   const char *proxy_pass;
2743   skip_certificate_check=0;
2744   proxy_host=NULL;
2745   proxy_port=8080;
2746   proxy_user=NULL;
2747   proxy_pass=NULL;
2748   for(;;){
2749     ptrdiff_t request;
2750     request=va_arg(_ap,char *)-(char *)NULL;
2751     /*If we hit NULL, we're done processing options.*/
2752     if(!request)break;
2753     switch(request){
2754       case OP_SSL_SKIP_CERTIFICATE_CHECK_REQUEST:{
2755         skip_certificate_check=!!va_arg(_ap,opus_int32);
2756       }break;
2757       case OP_HTTP_PROXY_HOST_REQUEST:{
2758         proxy_host=va_arg(_ap,const char *);
2759       }break;
2760       case OP_HTTP_PROXY_PORT_REQUEST:{
2761         proxy_port=va_arg(_ap,opus_int32);
2762         if(proxy_port<0||proxy_port>(opus_int32)65535)return NULL;
2763       }break;
2764       case OP_HTTP_PROXY_USER_REQUEST:{
2765         proxy_user=va_arg(_ap,const char *);
2766       }break;
2767       case OP_HTTP_PROXY_PASS_REQUEST:{
2768         proxy_pass=va_arg(_ap,const char *);
2769       }break;
2770       /*Some unknown option.*/
2771       default:return NULL;
2772     }
2773   }
2774   return op_url_stream_create_impl(_cb,_url,skip_certificate_check,
2775    proxy_host,proxy_port,proxy_user,proxy_pass);
2776 }
2777
2778 void *op_url_stream_create(OpusFileCallbacks *_cb,
2779  const char *_url,...){
2780   va_list ap;
2781   va_start(ap,_url);
2782   return op_url_stream_vcreate(_cb,_url,ap);
2783 }