207
207
#if defined(OP_ENABLE_HTTP)
208
# include <sys/ioctl.h>
209
# include <sys/types.h>
210
# include <sys/socket.h>
209
# include <winsock2.h>
210
# include <ws2tcpip.h>
211
# include <openssl/ssl.h>
212
# include "winerrno.h"
214
typedef SOCKET op_sock;
216
# define OP_INVALID_SOCKET (INVALID_SOCKET)
218
/*Vista and later support WSAPoll(), but we don't want to rely on that.
219
Instead we re-implement it badly using select().
220
Unfortunately, they define a conflicting struct pollfd, so we only define our
221
own if it looks like that one has not already been defined.*/
222
# if !defined(POLLIN)
223
/*Equivalent to POLLIN.*/
224
# define POLLRDNORM (0x0100)
225
/*Priority band data can be read.*/
226
# define POLLRDBAND (0x0200)
227
/*There is data to read.*/
228
# define POLLIN (POLLRDNORM|POLLRDBAND)
229
/* There is urgent data to read.*/
230
# define POLLPRI (0x0400)
231
/*Equivalent to POLLOUT.*/
232
# define POLLWRNORM (0x0010)
233
/*Writing now will not block.*/
234
# define POLLOUT (POLLWRNORM)
235
/*Priority data may be written.*/
236
# define POLLWRBAND (0x0020)
237
/*Error condition (output only).*/
238
# define POLLERR (0x0001)
239
/*Hang up (output only).*/
240
# define POLLHUP (0x0002)
241
/*Invalid request: fd not open (output only).*/
242
# define POLLNVAL (0x0004)
247
/*Requested events.*/
254
/*But Winsock never defines nfds_t (it's simply hard-coded to ULONG).*/
255
typedef unsigned long nfds_t;
257
/*The usage of FD_SET() below is O(N^2).
258
This is okay because select() is limited to 64 sockets in Winsock, anyway.
259
In practice, we only ever call it with one or two sockets.*/
260
static int op_poll_win32(struct pollfd *_fds,nfds_t _nfds,int _timeout){
270
for(i=0;i<_nfds;i++){
272
if(_fds[i].events&POLLIN)FD_SET(_fds[i].fd,&ifds);
273
if(_fds[i].events&POLLOUT)FD_SET(_fds[i].fd,&ofds);
274
FD_SET(_fds[i].fd,&efds);
277
tv.tv_sec=_timeout/1000;
278
tv.tv_usec=(_timeout%1000)*1000;
280
ret=select(-1,&ifds,&ofds,&efds,_timeout<0?NULL:&tv);
282
for(i=0;i<_nfds;i++){
283
if(FD_ISSET(_fds[i].fd,&ifds))_fds[i].revents|=POLLIN;
284
if(FD_ISSET(_fds[i].fd,&ofds))_fds[i].revents|=POLLOUT;
285
/*This isn't correct: there are several different things that might have
286
happened to a fd in efds, but I don't know a good way to distinguish
287
them without more context from the caller.
288
It's okay, because we don't actually check any of these bits, we just
289
need _some_ bit set.*/
290
if(FD_ISSET(_fds[i].fd,&efds))_fds[i].revents|=POLLHUP;
296
/*We define op_errno() to make it clear that it's not an l-value like normal
298
# define op_errno() (WSAGetLastError()?WSAGetLastError()-WSABASEERR:0)
299
# define op_reset_errno() (WSASetLastError(0))
301
/*The remaining functions don't get an op_ prefix even though they only
302
operate on sockets, because we don't use non-socket I/O here, and this
303
minimizes the changes needed to deal with Winsock.*/
304
# define close(_fd) closesocket(_fd)
305
/*This relies on sizeof(u_long)==sizeof(int), which is always true on both
307
# define ioctl(_fd,_req,_arg) ioctlsocket(_fd,_req,(u_long *)(_arg))
308
# define getsockopt(_fd,_level,_name,_val,_len) \
309
getsockopt(_fd,_level,_name,(char *)(_val),_len)
310
# define setsockopt(_fd,_level,_name,_val,_len) \
311
setsockopt(_fd,_level,_name,(const char *)(_val),_len)
312
# define poll(_fds,_nfds,_timeout) op_poll_win32(_fds,_nfds,_timeout)
314
# if defined(_MSC_VER)
315
typedef ptrdiff_t ssize_t;
318
/*Load certificates from the built-in certificate store.*/
319
int SSL_CTX_set_default_verify_paths_win32(SSL_CTX *_ssl_ctx);
320
# define SSL_CTX_set_default_verify_paths \
321
SSL_CTX_set_default_verify_paths_win32
324
/*Normal Berkeley sockets.*/
325
# include <sys/ioctl.h>
326
# include <sys/types.h>
327
# include <sys/socket.h>
328
# include <arpa/inet.h>
329
# include <netinet/in.h>
330
# include <netinet/tcp.h>
335
# include <openssl/ssl.h>
339
# define OP_INVALID_SOCKET (-1)
341
# define op_errno() (errno)
342
# define op_reset_errno() (errno=0)
211
345
# include <sys/timeb.h>
212
# include <arpa/inet.h>
213
# include <netinet/in.h>
214
# include <netinet/tcp.h>
219
# include <openssl/ssl.h>
220
346
# include <openssl/x509v3.h>
222
348
/*The maximum number of simultaneous connections.
582
708
memset(&hints,0,sizeof(hints));
583
709
hints.ai_socktype=SOCK_STREAM;
584
711
hints.ai_flags=AI_NUMERICSERV;
585
713
OP_ASSERT(_port<=65535U);
586
714
sprintf(service,"%u",_port);
587
715
if(OP_LIKELY(!getaddrinfo(_host,service,&hints,&addrs)))return addrs;
591
static int op_sock_set_nonblocking(int _fd,int _nonblocking){
719
static int op_sock_set_nonblocking(op_sock _fd,int _nonblocking){
593
722
flags=fcntl(_fd,F_GETFL);
594
723
if(OP_UNLIKELY(flags<0))return flags;
595
724
if(_nonblocking)flags|=O_NONBLOCK;
596
725
else flags&=~O_NONBLOCK;
597
726
return fcntl(_fd,F_SETFL,flags);
728
return ioctl(_fd,FIONBIO,&_nonblocking);
600
732
/*Disable/enable write coalescing if we can.
601
733
We always send whole requests at once and always parse the response headers
602
734
before sending another one, so normally write coalescing just causes added
604
static void op_sock_set_tcp_nodelay(int _fd,int _nodelay){
736
static void op_sock_set_tcp_nodelay(op_sock _fd,int _nodelay){
605
737
# if defined(TCP_NODELAY)&&(defined(IPPROTO_TCP)||defined(SOL_TCP))
606
738
# if defined(IPPROTO_TCP)
607
739
# define OP_SO_LEVEL IPPROTO_TCP
3070
3214
void *op_url_stream_create(OpusFileCallbacks *_cb,
3071
3215
const char *_url,...){
3073
3218
va_start(ap,_url);
3074
return op_url_stream_vcreate(_cb,_url,ap);
3219
ret=op_url_stream_vcreate(_cb,_url,ap);
3224
/*Convenience routines to open/test URLs in a single step.*/
3226
OggOpusFile *op_vopen_url(const char *_url,int *_error,va_list _ap){
3227
OpusFileCallbacks cb;
3230
source=op_url_stream_vcreate(&cb,_url,_ap);
3231
if(OP_UNLIKELY(source==NULL)){
3232
if(_error!=NULL)*_error=OP_EFAULT;
3235
of=op_open_callbacks(source,&cb,NULL,0,_error);
3236
if(OP_UNLIKELY(of==NULL))(*cb.close)(source);
3240
OggOpusFile *op_open_url(const char *_url,int *_error,...){
3243
va_start(ap,_error);
3244
ret=op_vopen_url(_url,_error,ap);
3249
OggOpusFile *op_vtest_url(const char *_url,int *_error,va_list _ap){
3250
OpusFileCallbacks cb;
3253
source=op_url_stream_vcreate(&cb,_url,_ap);
3254
if(OP_UNLIKELY(source==NULL)){
3255
if(_error!=NULL)*_error=OP_EFAULT;
3258
of=op_test_callbacks(source,&cb,NULL,0,_error);
3259
if(OP_UNLIKELY(of==NULL))(*cb.close)(source);
3263
OggOpusFile *op_test_url(const char *_url,int *_error,...){
3266
va_start(ap,_error);
3267
ret=op_vtest_url(_url,_error,ap);