/** * lw6sys_url_parse * * @sys_context: global system context * @url: the URL to parse * * Parses a URL, this is not a complete RFC compliant * parser, it's only used to transform URLs into * their 'canonical' form as well as getting basic * info such as on which port one should connect. * * Return value: a newly allocated struct, NULL on error */ lw6sys_url_t * lw6sys_url_parse (lw6sys_context_t * sys_context, const char *url) { lw6sys_url_t *ret = NULL; char *tmp = NULL; char *pos = NULL; char *seek = NULL; char seek_c = '\0'; ret = (lw6sys_url_t *) LW6SYS_CALLOC (sys_context, sizeof (lw6sys_url_t)); if (ret) { tmp = lw6sys_str_copy (sys_context, url); lw6sys_str_cleanup_ascii7 (sys_context, tmp); if (lw6sys_str_starts_with (sys_context, tmp, _HTTPS)) { ret->use_ssl = 1; } pos = tmp; seek = strstr (pos, _DOT_DOT_SLASH_SLASH); if (seek) { pos = seek + strlen (_DOT_DOT_SLASH_SLASH); } lw6sys_log (sys_context, LW6SYS_LOG_DEBUG, _x_ ("interpreting host, remaining string is \"%s\""), pos); seek = pos; while (_is_host (*seek)) { seek++; } seek_c = (*seek); (*seek) = '\0'; lw6sys_str_tolower (sys_context, pos); if (strlen (pos) > 0) { ret->host = lw6sys_str_copy (sys_context, pos); } else { ret->host = lw6sys_str_copy (sys_context, _LOCALHOST); } (*seek) = seek_c; pos = seek; if ((*pos) == _DOT_DOT) { lw6sys_log (sys_context, LW6SYS_LOG_DEBUG, _x_ ("port detected, remaining string is \"%s\""), pos); pos++; seek = pos; while (_is_port (*seek)) { seek++; } seek_c = (*seek); (*seek) = '\0'; ret->port = lw6sys_atoi (sys_context, pos); (*seek) = seek_c; pos = seek; } else { lw6sys_log (sys_context, LW6SYS_LOG_DEBUG, _x_ ("no port detected, remaining string is \"%s\""), pos); if (ret->use_ssl) { ret->port = _HTTPS_PORT; } else { ret->port = _HTTP_PORT; } } if (ret->port <= 0 || ret->port > _MAX_PORT) { ret->port = _HTTP_PORT; } lw6sys_log (sys_context, LW6SYS_LOG_DEBUG, _x_ ("interpreting URI, remaining string is \"%s\""), pos); if (strlen (pos) > 0 && (*pos) == _SLASH) { ret->uri = lw6sys_escape_http_uri (sys_context, pos); } else { ret->uri = lw6sys_new_sprintf (sys_context, "%c", _SLASH); } if (ret->host && ret->uri) { // OK } else { lw6sys_url_free (sys_context, ret); ret = NULL; } LW6SYS_FREE (sys_context, tmp); } return ret; }
/* _look_knot(): read a step on a rope. */ u4_loaf _look_knot(u4_milr m, u4_knot vor, u4_mold typ) { u4_lane lane = m->lane; u4_tick tik; u4_term cox; u4_axis axe; u4_loaf fod; if ( _is_port(vor, &tik, &cox) ) { fod = _mill_find(m, cox, u4_noun_0, typ); if ( u4_n_zero(fod) ) { u4_burp(lane, "mold", _mill_dump(m, typ)); u4_burp(lane, "mark", u4_prep_textual(lane, cox)); return _mill_fail(m, "look: not found"); } else if ( u4_n_zero(tik) ) { return fod; } else { u4_mold lem = u4_ch(fod); u4_nock vil = u4_ct(fod); u4_noun p_vil; u4_mold ger; vor = u4_k_trel(lane, u4_atom_port, u4_op_dec(lane, tik), cox); if ( u4_b_p(vil, u4_noun_0, &axe) ) { ger = lem; } else if ( u4_b_pq(vil, u4_noun_3, &p_vil, 0) && u4_b_p(p_vil, u4_noun_0, &axe) && u4_b_pq(lem, u4_atom_hold, &ger, 0) ) { axe = u4_op_peg(lane, axe, u4_noun_2); vil = u4_k_cell(lane, u4_noun_0, axe); ger = _mill_peek(m, u4_noun_2, u4_noun_0, ger); } else return u4_trip; fod = _look_knot(m, vor, ger); if ( u4_n_zero(fod) ) { u4_burp(lane, "mold", _mill_dump(m, typ)); u4_burp(lane, "mark", u4_prep_textual(lane, cox)); return _mill_fail(m, "look: no grip"); } else { return u4_k_cell (lane, u4_ch(fod), _mill_comp(m, vil, u4_ct(fod))); } } } else if ( _is_frag(vor, &axe) ) { return u4_k_trel (lane, _mill_peek(m, axe, u4_noun_0, typ), u4_noun_0, axe); } else return u4_trip; }