uclient-example.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include <libubox/blobmsg.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include "uclient.h"
  5. static void example_header_done(struct uclient *cl)
  6. {
  7. struct blob_attr *cur;
  8. int rem;
  9. printf("Headers (%d): \n", cl->status_code);
  10. blobmsg_for_each_attr(cur, cl->meta, rem) {
  11. printf("%s=%s\n", blobmsg_name(cur), (char *) blobmsg_data(cur));
  12. }
  13. printf("Contents:\n");
  14. }
  15. static void example_read_data(struct uclient *cl)
  16. {
  17. char buf[256];
  18. int len;
  19. while (1) {
  20. len = uclient_read(cl, buf, sizeof(buf));
  21. if (!len)
  22. return;
  23. write(STDOUT_FILENO, buf, len);
  24. }
  25. }
  26. static void example_request_sm(struct uclient *cl)
  27. {
  28. static int i = 0;
  29. switch (i++) {
  30. case 0:
  31. uclient_connect(cl);
  32. uclient_http_set_request_type(cl, "HEAD");
  33. uclient_request(cl);
  34. break;
  35. case 1:
  36. uclient_connect(cl);
  37. uclient_http_set_request_type(cl, "GET");
  38. uclient_request(cl);
  39. break;
  40. default:
  41. uloop_end();
  42. break;
  43. };
  44. }
  45. static void example_eof(struct uclient *cl)
  46. {
  47. static int retries;
  48. if (retries < 10 && uclient_http_redirect(cl)) {
  49. retries++;
  50. return;
  51. }
  52. retries = 0;
  53. example_request_sm(cl);
  54. }
  55. static void example_error(struct uclient *cl, int code)
  56. {
  57. fprintf(stderr, "Error %d!\n", code);
  58. example_request_sm(cl);
  59. }
  60. static const struct uclient_cb cb = {
  61. .header_done = example_header_done,
  62. .data_read = example_read_data,
  63. .data_eof = example_eof,
  64. .error = example_error,
  65. };
  66. static int usage(const char *progname)
  67. {
  68. fprintf(stderr,
  69. "Usage: %s [options] <hostname> <port>\n"
  70. "Options:\n"
  71. " -c <cert>: Load CA certificates from file <cert>\n"
  72. " -C: Skip certificate CN verification against hostname\n"
  73. "\n", progname);
  74. return 1;
  75. }
  76. int main(int argc, char **argv)
  77. {
  78. struct ustream_ssl_ctx *ctx;
  79. const char *progname = argv[0];
  80. struct uclient *cl;
  81. bool verify = true;
  82. int ch;
  83. ctx = ustream_ssl_context_new(false);
  84. while ((ch = getopt(argc, argv, "Cc:")) != -1) {
  85. switch(ch) {
  86. case 'c':
  87. ustream_ssl_context_add_ca_crt_file(ctx, optarg);
  88. break;
  89. case 'C':
  90. verify = false;
  91. break;
  92. default:
  93. return usage(progname);
  94. }
  95. }
  96. argv += optind;
  97. argc -= optind;
  98. if (argc != 1)
  99. return usage(progname);
  100. uloop_init();
  101. cl = uclient_new(argv[0], &cb);
  102. if (!cl) {
  103. fprintf(stderr, "Failed to allocate uclient context\n");
  104. return 1;
  105. }
  106. uclient_http_set_ssl_ctx(cl, ctx, verify);
  107. example_request_sm(cl);
  108. uloop_run();
  109. uloop_done();
  110. uclient_free(cl);
  111. ustream_ssl_context_free(ctx);
  112. return 0;
  113. }