MHEG-5  19.3.0
MHEG-5 Documentation
curlInterface.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2010 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
25 /*---includes for this file--------------------------------------------------*/
26 #include "http_platform.h"
27 
28 #include <assert.h>
29 #include <string.h>
30 
31 #include <curl/curl.h>
32 
33 #include <openssl/ssl.h>
34 
35 #include "dvb_misc.h"
36 #include "stb_memory.h"
37 #include "stb_os.h"
38 #include "glue_debug.h"
39 
40 /*---constant definitions for this file--------------------------------------*/
41 
42 #define HTTP_IDLE_TIMEOUT 200 /* ms */
43 #define MAX_USER_AGENT 256
44 
45 #define CHK_EASY(call) \
46  { \
47  CURLcode code; \
48  code = (call); \
49  if (code != CURLE_OK) \
50  { \
51  TRACE(TERROR, ("FAIL %s",#call)) \
52  return FALSE; \
53  } \
54  }
55 
56 //#define HTTP_DEBUG
57 #ifdef HTTP_DEBUG
58 #define DBG_ENTRY(x) DBG_PRINTF(" >> %s\n", #x);
59 #define DBG_EXIT(x) DBG_PRINTF(" << %s\n", #x);
60 #else
61 #define DBG_ENTRY(x)
62 #define DBG_EXIT(x)
63 #endif
64 
65 
66 /*---local typedef structs for this file-------------------------------------*/
67 typedef struct
68 {
69  size_t size;
70  void *ptr;
71 } AllocInfo_t;
72 
73 typedef struct HttpClientInfo_tag
74 {
75  void *userdata;
76  struct curl_slist *headers;
78 
79 typedef struct HttpCertList_tag
80 {
81  struct HttpCertList_tag *next;
82  X509 *x509;
84 
85 
86 /*---local (static) variable declarations for this file----------------------*/
87 static CURLM *multi_handle = NULL;
88 static HttpCertList_t http_cert_list = NULL;
89 static void *ssl_mutex;
90 
91 static char http_user_agent[MAX_USER_AGENT] = "";
92 static U16BIT http_timeout = 30;
93 static char curl_error_buffer[CURL_ERROR_SIZE];
94 
95 /*---local function definitions----------------------------------------------*/
96 
97 /*---global function definitions---------------------------------------------*/
98 
99 static size_t httpWriteCallback(void *ptr, size_t size,
100  size_t nmemb, void *handle);
101 static size_t httpHeaderCallback(void *ptr, size_t size,
102  size_t nmemb, void *handle);
103 static void* httpParseCertificate(U8BIT *buffer, U16BIT length);
104 static CURLcode httpSslCtxFunction(CURL *curl, void *sslctx, void *parm);
105 
111 E_HttpErr HP_Initialise(void)
112 {
113  E_HttpErr err;
114 
115  DBG_ENTRY(HP_Initialise);
116 
117  ssl_mutex = STB_OSCreateMutex();
118 
119  multi_handle = curl_multi_init();
120  if (multi_handle != NULL)
121  {
122  err = HTTP_OK;
123  }
124  else
125  {
126  err = HTTP_ERR_INTERNAL;
127  }
128 
129  DBG_EXIT(HP_Initialise);
130 
131  return err;
132 }
133 
140 E_HttpErr HP_SetUserAgent(U8BIT *user_agent)
141 {
142  DBG_ENTRY(HP_SetUserAgent);
143 
144  strcpy(http_user_agent, (char *)user_agent);
145 
146  DBG_EXIT(HP_SetUserAgent);
147 
148  return HTTP_OK;
149 }
150 
163 E_HttpErr HP_SetTimeout(U16BIT timeout)
164 {
165  DBG_ENTRY(HP_SetTimeout);
166 
167  http_timeout = timeout;
168 
169  DBG_EXIT(HP_SetTimeout);
170 
171  return HTTP_OK;
172 }
173 
187 E_HttpErr HP_CreateRequest(U8BIT *url, E_HttpRequestType type,
188  void **handle)
189 {
190  HttpClientInfo_t client_info;
191  E_HttpErr err;
192 
193  DBG_ENTRY(HP_CreateRequest);
194 
195  if (handle != NULL)
196  {
197  *handle = curl_easy_init();
198  if (*handle != NULL)
199  {
200  client_info = STB_MemAlloc(sizeof *client_info);
201  if (client_info != NULL)
202  {
203  client_info->userdata = NULL;
204  client_info->headers = NULL;
205 
206  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_URL, (U8BIT *)url));
207  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_PRIVATE, client_info));
208 
209  if (http_user_agent[0] != '\0')
210  {
211  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_USERAGENT,
212  http_user_agent));
213  }
214 
215  curl_error_buffer[0] = 0;
216  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_ERRORBUFFER,
217  curl_error_buffer));
218  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_WRITEFUNCTION,
219  httpWriteCallback));
220  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_WRITEDATA, *handle));
221  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_HEADERFUNCTION,
222  httpHeaderCallback));
223  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_WRITEHEADER, *handle));
224 
225  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_HEADER, 0));
226  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_NOPROGRESS, 1));
227  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_HTTP_VERSION,
228  CURL_HTTP_VERSION_1_1));
229 
230  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_SSL_CTX_FUNCTION,
231  httpSslCtxFunction));
232  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_SSL_CIPHER_LIST,
233  "aRSA:MD5:SHA:eNULL"));
234  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_CAINFO, NULL));
235 
236  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_CONNECTTIMEOUT,
237  http_timeout));
238  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_LOW_SPEED_LIMIT, 32));
239  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_LOW_SPEED_TIME,
240  http_timeout));
241 
242  switch (type)
243  {
244  case HTTP_REQUEST_GET:
245  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_HTTPGET, 1));
246  break;
247  case HTTP_REQUEST_HEAD:
248  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_NOBODY, 1));
249  break;
250  case HTTP_REQUEST_POST:
251  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_POST, 1));
252  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_POSTFIELDS, ""));
253  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_POSTFIELDSIZE, 0));
254  break;
255  case HTTP_REQUEST_STREAM:
256  CHK_EASY(curl_easy_setopt(*handle, CURLOPT_HTTPGET, 1));
257  break;
258  }
259  }
260  else
261  {
262  curl_easy_cleanup(*handle);
263  *handle = NULL;
264  }
265  }
266  err = HTTP_OK;
267  }
268  else
269  {
270  err = HTTP_ERR_BAD_PARAMETER;
271  }
272 
273  DBG_EXIT(HP_CreateRequest);
274 
275  return err;
276 }
277 
285 E_HttpErr HP_StartRequest(void *handle)
286 {
287  void *private;
288  HttpClientInfo_t client_info;
289  CURLcode code;
290  CURLMcode multi_code;
291  E_HttpErr err;
292 
293  DBG_ENTRY(HP_StartRequest);
294 
295  err = HTTP_ERR_INTERNAL;
296 
297  if (handle != NULL)
298  {
299  code = CURLE_OK;
300 
301  /* Commit HTTP headers */
302  curl_easy_getinfo(handle, CURLINFO_PRIVATE, &private);
303  client_info = private;
304  if (client_info->headers != NULL)
305  {
306  code = curl_easy_setopt(handle, CURLOPT_HTTPHEADER,
307  client_info->headers);
308  }
309 
310  if (code == CURLE_OK)
311  {
312  /* Add handle to multi handle */
313  multi_code = curl_multi_add_handle(multi_handle, handle);
314  if (multi_code == CURLM_OK)
315  {
316  err = HTTP_OK;
317  }
318  else
319  {
320  TRACE(TERROR,("curl_multi_add_handle %d",multi_code))
321  }
322  }
323  else
324  {
325  TRACE(TERROR,("curl_easy_setopt d",code))
326  }
327  }
328  else
329  {
330  err = HTTP_ERR_BAD_PARAMETER;
331  }
332 
333  DBG_EXIT(HP_StartRequest);
334 
335  return err;
336 }
337 
345 E_HttpErr HP_ResumeRequest(void *handle)
346 {
347  CURLcode code;
348  U16BIT dummy;
349  E_HttpErr err;
350 
351  DBG_ENTRY(HP_ResumeRequest);
352 
353  err = HTTP_ERR_INTERNAL;
354 
355  if (handle != NULL)
356  {
357  code = curl_easy_pause(handle, CURLPAUSE_CONT);
358  if (code == CURLE_OK)
359  {
360  /* Continue the transfer */
361  HP_Process(&dummy);
362  err = HTTP_OK;
363  }
364  else
365  {
366  TRACE(TERROR,("CURL error %d",code))
367  }
368  }
369  else
370  {
371  err = HTTP_ERR_BAD_PARAMETER;
372  }
373 
374  DBG_EXIT(HP_ResumeRequest);
375 
376  return err;
377 }
378 
386 E_HttpErr HP_StopRequest(void *handle)
387 {
388  CURLMcode multi_code;
389  E_HttpErr err;
390 
391  DBG_ENTRY(HP_StopRequest);
392 
393  err = HTTP_ERR_INTERNAL;
394 
395  if (handle != NULL)
396  {
397  multi_code = curl_multi_remove_handle(multi_handle, handle);
398  if (multi_code == CURLM_OK)
399  {
400  err = HTTP_OK;
401  }
402  }
403  else
404  {
405  err = HTTP_ERR_BAD_PARAMETER;
406  }
407 
408  DBG_EXIT(HP_StopRequest);
409 
410  return err;
411 }
412 
420 E_HttpErr HP_DestroyRequest(void *handle)
421 {
422  void *private;
423  HttpClientInfo_t client_info;
424  E_HttpErr err;
425 
426  DBG_ENTRY(HP_DestroyRequest);
427 
428  err = HTTP_ERR_INTERNAL;
429 
430  if (handle != NULL)
431  {
432  /* Clear client information */
433  curl_easy_getinfo(handle, CURLINFO_PRIVATE, &private);
434  client_info = private;
435  if (client_info->headers != NULL)
436  {
437  curl_easy_setopt(handle, CURLOPT_HTTPHEADER, NULL);
438  curl_slist_free_all(client_info->headers);
439  client_info->headers = NULL;
440  }
441  STB_MemFree(client_info);
442 
443  /* Clean curl handle */
444  curl_easy_cleanup(handle);
445  }
446  else
447  {
448  err = HTTP_ERR_BAD_PARAMETER;
449  }
450 
451  DBG_EXIT(HP_DestroyRequest);
452 
453  return err;
454 }
455 
464 E_HttpErr HP_SetUserData(void *handle, void *userdata)
465 {
466  void *private;
467  HttpClientInfo_t client_info;
468  E_HttpErr err;
469 
470  DBG_ENTRY(HP_SetUserData);
471 
472  err = HTTP_ERR_INTERNAL;
473 
474  if (handle != NULL)
475  {
476  curl_easy_getinfo(handle, CURLINFO_PRIVATE, &private);
477  client_info = private;
478  client_info->userdata = userdata;
479  err = HTTP_OK;
480  }
481  else
482  {
483  err = HTTP_ERR_BAD_PARAMETER;
484  }
485 
486  DBG_EXIT(HP_SetUserData);
487 
488  return err;
489 }
490 
499 E_HttpErr HP_AddHeader(void *handle, U8BIT *header)
500 {
501  void *private;
502  HttpClientInfo_t client_info;
503  E_HttpErr err;
504 
505  DBG_ENTRY(HP_AddHeader);
506 
507  err = HTTP_ERR_INTERNAL;
508 
509  if (handle != NULL && header != NULL)
510  {
511  curl_easy_getinfo(handle, CURLINFO_PRIVATE, &private);
512  client_info = private;
513  client_info->headers = curl_slist_append(client_info->headers,
514  (char *)header);
515  err = HTTP_OK;
516  }
517  else
518  {
519  err = HTTP_ERR_BAD_PARAMETER;
520  }
521 
522  DBG_EXIT(HP_AddHeader);
523 
524  return err;
525 }
526 
535 E_HttpErr HP_SetPostData(void *handle, U8BIT *postdata)
536 {
537  CURLcode code;
538  E_HttpErr err;
539 
540  DBG_ENTRY(HP_SetPostData);
541 
542  err = HTTP_ERR_INTERNAL;
543 
544  if (handle != NULL && postdata != NULL)
545  {
546  code = curl_easy_setopt(handle, CURLOPT_POSTFIELDS, postdata);
547  if (code == CURLE_OK)
548  {
549  code = curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE, -1);
550  if (code == CURLE_OK)
551  {
552  err = HTTP_OK;
553  }
554  }
555  }
556  else
557  {
558  err = HTTP_ERR_BAD_PARAMETER;
559  }
560 
561  DBG_EXIT(HP_SetPostData);
562 
563  return err;
564 }
565 
574 E_HttpErr HP_SetRange(void *handle, U8BIT *range)
575 {
576  E_HttpErr err;
577 
578  DBG_ENTRY(HP_SetRange);
579 
580  err = HTTP_ERR_INTERNAL;
581 
582  if (handle != NULL && range != NULL)
583  {
584  CHK_EASY(curl_easy_setopt(handle, CURLOPT_RANGE, range));
585  err = HTTP_OK;
586  }
587  else
588  {
589  err = HTTP_ERR_BAD_PARAMETER;
590  }
591 
592  DBG_EXIT(HP_SetRange);
593 
594  return err;
595 }
596 
605 E_HttpErr HP_GetRedirectUrl(void *handle, U8BIT **url)
606 {
607  CURLcode code;
608  char *redir_url;
609  E_HttpErr err;
610 
611  DBG_ENTRY(HP_GetRedirectUrl);
612 
613  err = HTTP_ERR_INTERNAL;
614 
615  if (handle != NULL && url != NULL)
616  {
617  code = curl_easy_getinfo(handle, CURLINFO_REDIRECT_URL, &redir_url);
618  if (code == CURLE_OK)
619  {
620  *url = (U8BIT *)redir_url;
621  err = HTTP_OK;
622  }
623  }
624  else
625  {
626  err = HTTP_ERR_BAD_PARAMETER;
627  }
628 
629  DBG_EXIT(HP_GetRedirectUrl);
630 
631  return err;
632 }
633 
642 E_HttpErr HP_AddTlsCertificate(U8BIT *cert, U32BIT len)
643 {
644  HttpCertList_t *pcert, curr;
645  E_HttpErr err;
646 
647  DBG_ENTRY(HP_AddTlsCertificate);
648 
649  err = HTTP_ERR_INTERNAL;
650 
651  if (cert != NULL && len > 0)
652  {
653  STB_OSMutexLock(ssl_mutex);
654  pcert = &http_cert_list;
655  while (*pcert != NULL)
656  {
657  pcert = &(*pcert)->next;
658  }
659 
660  curr = STB_MemAlloc(sizeof *curr);
661  if (curr != NULL)
662  {
663  curr->next = NULL;
664  curr->x509 = httpParseCertificate(cert, len);
665  if (curr->x509 != NULL)
666  {
667  /* Append certificate */
668  *pcert = curr;
669  err = HTTP_OK;
670  }
671  else
672  {
673  /* Cannot parse / create certificate */
674  STB_MemFree(curr);
675  }
676  }
677  STB_OSMutexUnlock(ssl_mutex);
678  }
679  else
680  {
681  err = HTTP_ERR_BAD_PARAMETER;
682  }
683 
684  DBG_EXIT(HP_AddTlsCertificate);
685 
686  return err;
687 }
688 
694 E_HttpErr HP_ClearTlsCertificates(void)
695 {
696  HttpCertList_t *pcert, curr;
697 
698  DBG_ENTRY(HP_ClearTlsCertificates);
699 
700  STB_OSMutexLock(ssl_mutex);
701  pcert = &http_cert_list;
702  while (*pcert != NULL)
703  {
704  curr = *pcert;
705  *pcert = (*pcert)->next;
706  X509_free(curr->x509);
707  STB_MemFree(curr);
708  }
709  STB_OSMutexUnlock(ssl_mutex);
710 
711  DBG_EXIT(HP_ClearTlsCertificates);
712 
713  return HTTP_OK;
714 }
715 
724 E_HttpErr HP_WaitForAction(void)
725 {
726  CURLMcode multi_code;
727  fd_set readfds;
728  fd_set writefds;
729  fd_set exceptfds;
730  int max_fd;
731  struct timeval timeout;
732  E_HttpErr err;
733 
734  DBG_ENTRY(HP_WaitForAction);
735 
736  err = HTTP_ERR_INTERNAL;
737 
738  /* Wait for activity on one or more sockets */
739  FD_ZERO(&readfds);
740  FD_ZERO(&writefds);
741  FD_ZERO(&exceptfds);
742 
743  multi_code = curl_multi_fdset(multi_handle, &readfds, &writefds,
744  &exceptfds, &max_fd);
745  if (multi_code == CURLM_OK)
746  {
747  if (max_fd >= 0)
748  {
749  timeout.tv_sec = 0;
750  timeout.tv_usec = HTTP_IDLE_TIMEOUT * 1000;
751  select(max_fd + 1, &readfds, &writefds, &exceptfds, &timeout);
752  }
753  err = HTTP_OK;
754  }
755 
756  DBG_EXIT(HP_WaitForAction);
757 
758  return err;
759 }
760 
769 E_HttpErr HP_Process(U16BIT *active_count)
770 {
771  int running_handles;
772  CURLMcode multi_code;
773  CURLMsg *multi_msg;
774  int msgs_in_queue;
775  void *private;
776  HttpClientInfo_t client_info;
777  E_HttpStatus status;
778  E_HttpErr err;
779 
780  DBG_ENTRY(HP_Process);
781 
782  err = HTTP_ERR_INTERNAL;
783 
784  do
785  {
786  multi_code = curl_multi_perform(multi_handle, &running_handles);
787  STB_OSTaskDelay(1);
788  }
789  while (multi_code == CURLM_CALL_MULTI_PERFORM);
790 
791  if (multi_code == CURLM_OK)
792  {
793  do
794  {
795  multi_msg = curl_multi_info_read(multi_handle, &msgs_in_queue);
796  if (multi_msg != NULL)
797  {
798  if (multi_msg->msg == CURLMSG_DONE)
799  {
800  curl_easy_getinfo(multi_msg->easy_handle,
801  CURLINFO_PRIVATE, &private);
802  client_info = private;
803  switch (multi_msg->data.result)
804  {
805  case CURLE_OK:
806  status = HTTP_STATUS_OK;
807  break;
808  case CURLE_PARTIAL_FILE:
809  status = HTTP_STATUS_PARTIAL;
810  break;
811  case CURLE_SSL_CACERT:
812  status = HTTP_STATUS_SSL_ERROR;
813  break;
814  case CURLE_COULDNT_RESOLVE_PROXY:
815  case CURLE_COULDNT_RESOLVE_HOST:
816  case CURLE_COULDNT_CONNECT:
817  status = HTTP_STATUS_NETWORK_ERROR;
818  break;
819  case CURLE_OPERATION_TIMEDOUT:
820  status = HTTP_STATUS_TIMEOUT;
821  break;
822  default:
823  status = HTTP_STATUS_OTHER_ERROR;
824  TRACE(TERROR,("error buffer=%s",curl_error_buffer));
825  }
826  TRACE(TICS, ("ud=%p status=%u rslt=%u", client_info->userdata, status, multi_msg->data.result));
827  HP_EndCallback(client_info->userdata, status);
828  }
829  else
830  {
831  TRACE(TERROR,("multi_msg->msg = %d\n", multi_msg->msg));
832  }
833  }
834  }
835  while (multi_msg != NULL);
836 
837  err = HTTP_OK;
838  }
839  else
840  {
841  TRACE(TERROR,("curl error %s", curl_multi_strerror(multi_code)));
842  }
843 
844  *active_count = running_handles;
845 
846  DBG_EXIT(HP_Process);
847 
848  return err;
849 }
850 
856 E_HttpErr HP_Terminate(void)
857 {
858  DBG_ENTRY(HP_Terminate);
859 
860  if (multi_handle != NULL)
861  {
862  curl_multi_cleanup(multi_handle);
863  multi_handle = NULL;
864  }
865 
866  curl_global_cleanup();
867 
868  STB_OSDeleteMutex(ssl_mutex);
869 
870  DBG_EXIT(HP_Terminate);
871 
872  return HTTP_OK;
873 }
874 
883 static size_t httpHeaderCallback(void *ptr, size_t size,
884  size_t nmemb, void *handle)
885 {
886  long response_code;
887  void *private;
888  HttpClientInfo_t client_info;
889 
890  DBG_ENTRY(httpHeaderCallback);
891 
892  curl_easy_getinfo(handle, CURLINFO_PRIVATE, &private);
893  curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &response_code);
894 
895  client_info = private;
896  TRACE(TICS, ("itm size=%u num=%u ptr=%p", size, nmemb, ptr));
897  HP_HeaderCallback(client_info->userdata, response_code,
898  ptr, size * nmemb);
899 
900  DBG_EXIT(httpHeaderCallback);
901 
902  return size * nmemb;
903 }
904 
913 static size_t httpWriteCallback(void *ptr, size_t size,
914  size_t nmemb, void *handle)
915 {
916  size_t retval;
917  BOOLEAN processed;
918  void *private;
919  HttpClientInfo_t client_info;
920 
921  DBG_ENTRY(httpWriteCallback);
922 
923  retval = size * nmemb;
924 
925  curl_easy_getinfo(handle, CURLINFO_PRIVATE, &private);
926  client_info = private;
927  TRACE(TICS, ("itm size=%u num=%u ptr=%p", size, nmemb, ptr));
928  processed = HP_ContentCallback(client_info->userdata, ptr, size * nmemb);
929  if (!processed)
930  {
931  /* Pause the connection */
932  retval = CURL_WRITEFUNC_PAUSE;
933  }
934 
935  DBG_EXIT(httpWriteCallback);
936 
937  return retval;
938 }
939 
946 static void* httpParseCertificate(U8BIT *buffer, U16BIT length)
947 {
948  BIO *bio;
949  X509 *x509;
950  void *cert;
951 
952  DBG_ENTRY(httpParseCertificate);
953 
954  cert = NULL;
955 
956  bio = BIO_new_mem_buf(buffer, length);
957  if (bio != NULL)
958  {
959  x509 = d2i_X509_bio(bio, NULL);
960  if (x509 != NULL)
961  {
962  cert = x509;
963  }
964  BIO_free(bio);
965  }
966 
967  DBG_EXIT(httpParseCertificate);
968 
969  return cert;
970 }
971 
979 static CURLcode httpSslCtxFunction(CURL *curl, void *sslctx, void *parm)
980 {
981  SSL_CTX *ssl_ctx = sslctx;
982  X509_STORE *x509_store;
983  HttpCertList_t curr;
984  X509_VERIFY_PARAM *param;
985  S_DateTime date_time;
986  struct tm tmstruct;
987  time_t current_time;
988  CURLcode rc;
989 
990  DBG_ENTRY(sslCtxFunction);
991 
992  rc = CURLE_OK;
993  x509_store = SSL_CTX_get_cert_store(ssl_ctx);
994  if (x509_store != NULL)
995  {
996  /* Setup certificate store */
997  STB_OSMutexLock(ssl_mutex);
998 
999  curr = http_cert_list;
1000  while (curr != NULL)
1001  {
1002  if (X509_STORE_add_cert(x509_store, curr->x509) == 0)
1003  {
1004  TRACE(TERROR,("failed to ADD cert"));
1005  rc = CURLE_SSL_CERTPROBLEM;
1006  break;
1007  }
1008  curr = curr->next;
1009  }
1010 
1011  if (rc == CURLE_OK)
1012  {
1013  /* Set date for certificate varification */
1014  param = X509_VERIFY_PARAM_new();
1015  if (param != NULL)
1016  {
1017  DVB_MhegGetLocalTime(&date_time);
1018  tmstruct.tm_sec = date_time.second;
1019  tmstruct.tm_min = date_time.minute;
1020  tmstruct.tm_hour = date_time.hour;
1021  tmstruct.tm_mday = date_time.day;
1022  tmstruct.tm_mon = date_time.month - 1;
1023  tmstruct.tm_year = date_time.year - 1900;
1024  tmstruct.tm_isdst = 0;
1025  current_time = mktime(&tmstruct);
1026  X509_VERIFY_PARAM_set_time(param, current_time);
1027  X509_STORE_set1_param(x509_store, param);
1028  X509_VERIFY_PARAM_free(param);
1029  }
1030  }
1031 
1032  STB_OSMutexUnlock(ssl_mutex);
1033  }
1034  else
1035  {
1036  TRACE(TERROR,("failed to GET cert"));
1037  rc = CURLE_SSL_CERTPROBLEM;
1038  }
1039  TRACE(TICS, ("rc=%d", rc));
1040  DBG_EXIT(sslCtxFunction);
1041 
1042  return rc;
1043 }
1044 
E_HttpErr HP_CreateRequest(U8BIT *url, E_HttpRequestType type, void **handle)
Create an HTTP request. The URL is provided, and is guaranteed to be either "http://..." or "https://..." The request type is also provided. Streaming request is the same as a GET request, except that a "Range:" header is also allowed for it.
E_MhegErr DVB_MhegGetLocalTime(S_DateTime *pDateAndTime)
Provide the current local time and date, normally from the system real time clock, with any local time conversions (if necessary). The returned time should take into account local timezone and daylight saving settings.
E_HttpErr HP_Process(U16BIT *active_count)
Process HTTP requests. This may cause request callbacks to be called.
Manages the interface between HTTP component and platform.
void STB_OSTaskDelay(U16BIT timeout)
Delay Task for Specifed Time Period.
E_HttpErr HP_StartRequest(void *handle)
Start an HTTP request.
void STB_MemFree(void *ptr)
Releases previously allocated memory.
Debug tracing.
void STB_OSDeleteMutex(void *mutex)
Delete a mutex.
E_HttpErr HP_SetRange(void *handle, U8BIT *range)
Set "Range:" header for an HTTP request.
E_HttpErr HP_StopRequest(void *handle)
Stop an HTTP request.
System Memory allocation interface.
E_HttpErr HP_ClearTlsCertificates(void)
Clear TLS certificates.
E_HttpErr HP_GetRedirectUrl(void *handle, U8BIT **url)
Get redirection URL for HTTP request.
E_HttpErr HP_ResumeRequest(void *handle)
Resume an HTTP request.
void STB_OSMutexUnlock(void *mutex)
Unlock a mutex (a.k.a. &#39;leave&#39;, &#39;signal&#39; or &#39;release&#39;)
void * STB_MemAlloc(U32BIT memSize)
Allocates the specified number of bytes.
void * STB_OSCreateMutex(void)
Create a mutex.
E_HttpErr HP_WaitForAction(void)
Wait until there is some activity on one (or more) of the HTTP requests, or until some other conditio...
E_HttpErr HP_SetPostData(void *handle, U8BIT *postdata)
Set POST data for an HTTP request.
E_HttpErr HP_SetTimeout(U16BIT timeout)
Set timeout (in seconds) for HTTP requests. The timeout applies to connections (i.e. the time it takes to connect to the server) as well as response time (i.e the time it takes to download the content). Between sending the request and receiving the first byte of the the response there is no timeout.
BOOLEAN HP_ContentCallback(void *userdata, U8BIT *data, U32BIT len)
Callback for HTTP content data. This function is called by the HTTP client. The callback must return ...
E_HttpErr HP_Initialise(void)
Initialise the HTTP interface.
E_HttpErr HP_DestroyRequest(void *handle)
Destroy an HTTP request.
Definition: mg_png.c:52
void HP_HeaderCallback(void *userdata, S32BIT response_code, U8BIT *data, U32BIT len)
Callback for HTTP header data. This function is called by the HTTP client.
void STB_OSMutexLock(void *mutex)
Lock a mutex (a.k.a. &#39;enter&#39;, &#39;wait&#39; or &#39;get&#39;).
E_HttpErr HP_AddHeader(void *handle, U8BIT *header)
Add HTTP header to HTTP request.
References: [1] UK1 Profile - Digital Terrestrial Television - Requirements for interoperability (The...
E_HttpErr HP_SetUserAgent(U8BIT *user_agent)
Set user agent for HTTP client.
void HP_EndCallback(void *userdata, E_HttpStatus status)
Callback for HTTP request end. This function is called by the HTTP client.
E_HttpErr HP_SetUserData(void *handle, void *userdata)
Set user data associated with an HTTP request.
E_HttpErr HP_AddTlsCertificate(U8BIT *cert, U32BIT len)
Add a certificate for TLS connections.
E_HttpErr HP_Terminate(void)
Terminate the HTTP interface.
#define TRACE(t, x)
Definition: glue_debug.h:118
Header file - Function prototypes for operating system.