Rizin
unix-like reverse engineering framework and cli tools
socket_http.c File Reference
#include <rz_socket.h>
#include <rz_util.h>

Go to the source code of this file.

Macros

#define SOCKET_HTTP_MAX_HEADER_LENGTH   0x2000
 
#define SOCKET_HTTP_MAX_REDIRECTS   5
 

Functions

static size_t socket_slurp (RzSocket *s, RzBuffer *buf)
 
static char * socket_http_get_recursive (const char *url, int *code, int *rlen, ut32 redirections)
 
static char * socket_http_answer (RzSocket *s, int *code, int *rlen, ut32 redirections)
 
RZ_API char * rz_socket_http_get (const char *url, int *code, int *rlen)
 
RZ_API char * rz_socket_http_post (const char *url, const char *data, int *code, int *rlen)
 

Macro Definition Documentation

◆ SOCKET_HTTP_MAX_HEADER_LENGTH

#define SOCKET_HTTP_MAX_HEADER_LENGTH   0x2000

Definition at line 11 of file socket_http.c.

◆ SOCKET_HTTP_MAX_REDIRECTS

#define SOCKET_HTTP_MAX_REDIRECTS   5

Definition at line 12 of file socket_http.c.

Function Documentation

◆ rz_socket_http_get()

RZ_API char* rz_socket_http_get ( const char *  url,
int code,
int rlen 
)

Definition at line 287 of file socket_http.c.

287  {
289 }
url
Definition: setup.py:262
#define SOCKET_HTTP_MAX_REDIRECTS
Definition: socket_http.c:12
static char * socket_http_get_recursive(const char *url, int *code, int *rlen, ut32 redirections)
Definition: socket_http.c:191
Definition: inftree9.h:24

References socket_http_get_recursive(), SOCKET_HTTP_MAX_REDIRECTS, and setup::url.

Referenced by __open(), __read(), __rtr_shell(), __system(), __write(), download_and_write(), rtrcmd(), rz_core_rtr_add(), rz_core_rtr_cmd(), and rz_core_rtr_http_run().

◆ rz_socket_http_post()

RZ_API char* rz_socket_http_post ( const char *  url,
const char *  data,
int code,
int rlen 
)

Definition at line 291 of file socket_http.c.

291  {
292  RzSocket *s;
293  bool ssl = rz_str_startswith(url, "https://");
294  char *uri = strdup(url);
295  if (!uri) {
296  return NULL;
297  }
298 
299  char *host = strstr(uri, "://");
300  if (!host) {
301  free(uri);
302  printf("Invalid URI");
303  return NULL;
304  }
305  host += 3;
306  char *port = strchr(host, ':');
307  if (!port) {
308  port = (ssl) ? "443" : "80";
309  } else {
310  *port++ = 0;
311  }
312  char *path = strchr(host, '/');
313  if (!path) {
314  path = "";
315  } else {
316  *path++ = 0;
317  }
318  s = rz_socket_new(ssl);
319  if (!s) {
320  printf("Cannot create socket\n");
321  free(uri);
322  return NULL;
323  }
324  if (!rz_socket_connect_tcp(s, host, port, 0)) {
325  eprintf("Cannot connect to %s:%s\n", host, port);
326  free(uri);
327  return NULL;
328  }
329  /* Send */
331  "POST /%s HTTP/1.0\r\n"
332  "User-Agent: rizin " RZ_VERSION "\r\n"
333  "Accept: */*\r\n"
334  "Host: %s\r\n"
335  "Content-Length: %i\r\n"
336  "Content-Type: application/x-www-form-urlencoded\r\n"
337  "\r\n",
338  path, host, (int)strlen(data));
339  free(uri);
340  rz_socket_write(s, (void *)data, strlen(data));
341  return socket_http_answer(s, code, rlen, 0);
342 }
#define NULL
Definition: cris-opc.c:27
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
#define rz_socket_connect_tcp(a, b, c, d)
Definition: rz_socket.h:99
RZ_API void rz_socket_printf(RzSocket *s, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API RzSocket * rz_socket_new(bool is_ssl)
Definition: socket.c:179
RZ_API int rz_socket_write(RzSocket *s, void *buf, int len)
Definition: socket.c:724
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286
#define RZ_VERSION
Definition: rz_version.h:8
static char * socket_http_answer(RzSocket *s, int *code, int *rlen, ut32 redirections)
Definition: socket_http.c:34

References eprintf, free(), NULL, path, printf(), rz_socket_connect_tcp, rz_socket_new(), rz_socket_printf(), rz_socket_write(), rz_str_startswith(), RZ_VERSION, s, socket_http_answer(), strdup(), and setup::url.

◆ socket_http_answer()

static char* socket_http_answer ( RzSocket s,
int code,
int rlen,
ut32  redirections 
)
static

Definition at line 34 of file socket_http.c.

34  {
36  const char *p;
37  int ret, len = 0, delta = 0;
38  char *dn = NULL;
40  if (!b) {
41  return NULL;
42  }
43  char *res = NULL;
44  size_t olen = socket_slurp(s, b);
45  char *buf = malloc(olen + 1);
46  if (!buf) {
47  goto exit;
48  }
49  rz_buf_read_at(b, 0, (ut8 *)buf, olen);
50  buf[olen] = 0;
51  char *dnn = (char *)rz_str_casestr(buf, "\n\n");
52  char *drn = (char *)rz_str_casestr(buf, "\r\n\r\n");
53  if (dnn) {
54  if (drn && (drn < dnn)) {
55  dn = drn;
56  delta = 4;
57  } else {
58  dn = dnn;
59  delta = 2;
60  }
61  } else {
62  dn = drn;
63  delta = 4;
64  }
65  if (!dn) {
66  goto exit;
67  }
68 
69  olen -= delta;
70  *dn = 0; // chop headers
71 
72  /* Follow redirects */
73  p = rz_str_casestr(buf, "Location:");
74  if (p) {
75  if (!redirections) {
76  eprintf("Too many redirects\n");
77  goto exit;
78  }
79  p += strlen("Location:");
80  char *end_url = strchr(p, '\n');
81  if (end_url) {
82  int url_len = end_url - p;
83  char *url = rz_str_ndup(p, url_len);
85  res = socket_http_get_recursive(url, code, rlen, --redirections);
86  free(url);
87  len = *rlen;
88  }
89  goto exit;
90  }
91 
92  /* Parse Len */
93  p = rz_str_casestr(buf, "Content-Length: ");
94  if (p) {
95  len = atoi(p + 16);
96  } else {
97  len = olen - (dn - buf);
98  }
99  if (len > 0) {
100  if (len > olen) {
101  res = malloc(len + 2);
102  if (!res) {
103  goto exit;
104  }
105  olen -= dn - buf;
106  memcpy(res, dn + delta, olen);
107  do {
108  ret = rz_socket_read_block(s, (ut8 *)res + olen, len - olen);
109  if (ret < 1) {
110  break;
111  }
112  olen += ret;
113  } while (olen < len);
114  res[len] = 0;
115  } else {
116  res = malloc(len + 1);
117  if (res) {
118  memcpy(res, dn + delta, len);
119  res[len] = 0;
120  }
121  }
122  } else {
123  res = strdup("");
124  }
125 exit:
126  free(buf);
127  rz_buf_free(b);
129  if (rlen) {
130  *rlen = len;
131  }
132  return res;
133 }
size_t len
Definition: 6502dis.c:15
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * malloc(size_t size)
Definition: malloc.c:123
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API st64 rz_buf_read_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
Read len bytes of the buffer at the specified address.
Definition: buf.c:1136
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
Definition: buf.c:1253
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_bytes(RZ_NULLABLE RZ_BORROW const ut8 *bytes, ut64 len)
Creates a new buffer with a bytes array.
Definition: buf.c:465
RZ_API int rz_socket_close(RzSocket *s)
Definition: socket.c:419
RZ_API int rz_socket_read_block(RzSocket *s, unsigned char *buf, int len)
Definition: socket.c:808
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006
RZ_API void rz_str_trim(RZ_NONNULL RZ_INOUT char *str)
Removes whitespace characters (space, tab, newline etc.) from the beginning and end of a string.
Definition: str_trim.c:190
RZ_API const char * rz_str_casestr(const char *a, const char *b)
Definition: str.c:2757
#define b(i)
Definition: sha256.c:42
static size_t socket_slurp(RzSocket *s, RzBuffer *buf)
Definition: socket_http.c:14
static st64 delta
Definition: vmenus.c:2425

References b, delta, eprintf, test-lz4-list::exit, free(), len, malloc(), memcpy(), NULL, p, rz_buf_free(), rz_buf_new_with_bytes(), rz_buf_read_at(), rz_return_val_if_fail, rz_socket_close(), rz_socket_read_block(), rz_str_casestr(), rz_str_ndup(), rz_str_trim(), s, socket_http_get_recursive(), socket_slurp(), strdup(), and setup::url.

Referenced by rz_socket_http_post(), and socket_http_get_recursive().

◆ socket_http_get_recursive()

static char * socket_http_get_recursive ( const char *  url,
int code,
int rlen,
ut32  redirections 
)
static

Definition at line 191 of file socket_http.c.

191  {
192  if (code) {
193  *code = 0;
194  }
195  if (rlen) {
196  *rlen = 0;
197  }
198  char *curl_env = rz_sys_getenv("RZ_CURL");
199  if (!RZ_STR_ISEMPTY(curl_env) && atoi(curl_env)) {
200  int len;
201  char *escaped_url = rz_str_escape_sh(url);
202  char *command = rz_str_newf("curl -sfL -o - \"%s\"", escaped_url);
203  char *res = rz_sys_cmd_str(command, NULL, &len);
204  free(escaped_url);
205  free(command);
206  free(curl_env);
207  if (!res) {
208  return NULL;
209  }
210  if (res) {
211  if (code) {
212  *code = 200;
213  }
214  if (rlen) {
215  *rlen = len;
216  }
217  }
218  return res;
219  }
220  free(curl_env);
221 #if __WINDOWS__
222  return http_get_w32(url, code, rlen);
223 #else
224  RzSocket *s;
225  bool ssl = rz_str_startswith(url, "https://");
226 #if !HAVE_LIB_SSL
227  if (ssl) {
228  eprintf("Tried to get '%s', but SSL support is disabled, set RZ_CURL=1 to use curl\n", url);
229  return NULL;
230  }
231 #endif
232  char *response, *host, *path, *port = "80";
233  char *uri = strdup(url);
234  if (!uri) {
235  return NULL;
236  }
237  host = strstr(uri, "://");
238  if (!host) {
239  free(uri);
240  eprintf("rz_socket_http_get: Invalid URI");
241  return NULL;
242  }
243  host += 3;
244  port = strchr(host, ':');
245  if (!port) {
246 #if HAVE_LIB_SSL
247  port = ssl ? "443" : "80";
248 #else
249  port = "80";
250 #endif
251  path = host;
252  } else {
253  *port++ = 0;
254  path = port;
255  }
256  path = strchr(path, '/');
257  if (!path) {
258  path = "";
259  } else {
260  *path++ = 0;
261  }
262  s = rz_socket_new(ssl);
263  if (!s) {
264  eprintf("rz_socket_http_get: Cannot create socket\n");
265  free(uri);
266  return NULL;
267  }
268  if (rz_socket_connect_tcp(s, host, port, 0)) {
270  "GET /%s HTTP/1.1\r\n"
271  "User-Agent: rizin " RZ_VERSION "\r\n"
272  "Accept: */*\r\n"
273  "Host: %s:%s\r\n"
274  "\r\n",
275  path, host, port);
276  response = socket_http_answer(s, code, rlen, redirections);
277  } else {
278  eprintf("Cannot connect to %s:%s\n", host, port);
279  response = NULL;
280  }
281  free(uri);
282  rz_socket_free(s);
283  return response;
284 #endif
285 }
RZ_API int rz_socket_free(RzSocket *s)
Definition: socket.c:453
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67
RZ_API char * rz_str_escape_sh(const char *buf)
Definition: str.c:1560
RZ_API char * rz_sys_getenv(const char *key)
Get the value of an environment variable named key or NULL if none exists.
Definition: sys.c:483
RZ_API int RZ_API char * rz_sys_cmd_str(const char *cmd, const char *input, int *len)
Definition: sys.c:669
const char * command
Definition: main.c:7

References command, eprintf, free(), len, NULL, path, rz_socket_connect_tcp, rz_socket_free(), rz_socket_new(), rz_socket_printf(), rz_str_escape_sh(), RZ_STR_ISEMPTY, rz_str_newf(), rz_str_startswith(), rz_sys_cmd_str(), rz_sys_getenv(), RZ_VERSION, s, socket_http_answer(), strdup(), and setup::url.

Referenced by rz_socket_http_get(), and socket_http_answer().

◆ socket_slurp()

static size_t socket_slurp ( RzSocket s,
RzBuffer buf 
)
static

Definition at line 14 of file socket_http.c.

14  {
15  size_t i;
16  if (rz_socket_ready(s, 1, 0) != 1) {
17  return 0;
18  }
19  rz_socket_block_time(s, true, 0, 1000);
20  for (i = 0; i < SOCKET_HTTP_MAX_HEADER_LENGTH; i += 1) {
21  ut8 c;
22  int olen = rz_socket_read_block(s, &c, 1);
23  if (olen != 1) {
24  rz_buf_append_bytes(buf, (ut8 *)"", 1);
25  break;
26  }
28  }
29  return i;
30 }
lzma_index ** i
Definition: index.h:629
RZ_API bool rz_buf_append_bytes(RZ_NONNULL RzBuffer *b, RZ_NONNULL const ut8 *buf, ut64 len)
Append an array of bytes to the buffer.
Definition: buf.c:732
RZ_API int rz_socket_ready(RzSocket *s, int secs, int usecs)
Definition: socket.c:688
RZ_API bool rz_socket_block_time(RzSocket *s, bool block, int sec, int usec)
Definition: socket.c:649
#define c(i)
Definition: sha256.c:43
#define SOCKET_HTTP_MAX_HEADER_LENGTH
Definition: socket_http.c:11

References c, i, rz_buf_append_bytes(), rz_socket_block_time(), rz_socket_read_block(), rz_socket_ready(), s, and SOCKET_HTTP_MAX_HEADER_LENGTH.

Referenced by socket_http_answer().