static void _sg_password__parse_url( SG_context *pCtx, const char *url, SG_bool *pIsValid, SG_string **ppProto, SG_string **ppServer, SG_string **ppPath, SG_uint32 *pPort ) { const char *slash, *colon, *ss; SG_string *server = NULL; SG_string *path = NULL; SG_string *proto = NULL; SG_NULLARGCHECK(url); *pIsValid = SG_FALSE; if (strncmp("http://", url, 7) == 0) { SG_ERR_CHECK( SG_STRING__ALLOC__SZ(pCtx, &proto, "http") ); *pPort = 80; url += 7; } else if (strncmp("https://", url, 8) == 0) { SG_ERR_CHECK( SG_STRING__ALLOC__SZ(pCtx, &proto, "https") ); *pPort = 443; url += 8; } else goto fail; slash = strchr(url, '/'); if (! slash) goto fail; SG_ERR_CHECK( SG_STRING__ALLOC__BUF_LEN(pCtx, &server, (const SG_byte *)url, (SG_uint32)(slash - url)) ); ss = SG_string__sz(server); colon = strchr(ss, ':'); if (colon) { SG_uint32 port = atoi(colon + 1); SG_uint32 plen = colon - ss; if (port == 0) goto fail; *pPort = port; SG_ERR_CHECK( SG_string__remove(pCtx, server, plen, SG_STRLEN(ss) - plen) ); } SG_ERR_CHECK( SG_STRING__ALLOC__SZ(pCtx, &path, "/") ); *ppPath = path; path = NULL; *ppServer = server; server = NULL; *ppProto = proto; proto = NULL; *pIsValid = SG_TRUE; fail: SG_STRING_NULLFREE(pCtx, server); SG_STRING_NULLFREE(pCtx, path); SG_STRING_NULLFREE(pCtx, proto); }
static void _templatize( SG_context *pCtx, SG_string *content, const _request_headers *pRequestHeaders, _replacer_cb replacer) { SG_string *instr = NULL; const char *next = NULL; SG_string *piece = NULL; SG_string *replacement = NULL; SG_string *inclusion = NULL; SG_string *replaceRaw = NULL; SG_ERR_CHECK( SG_STRING__ALLOC__COPY(pCtx, &instr, content) ); SG_ERR_CHECK( SG_string__clear(pCtx, content) ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &piece) ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &replacement) ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &replaceRaw) ); next = SG_string__sz(instr); while (*next) { const char *delim = strstr(next, "{{{"); if (delim == NULL) { SG_ERR_CHECK( SG_string__append__sz(pCtx, content, next) ); break; } else { const char *rest = delim + 3; const char *end = strstr(rest, "}}}"); if (end == NULL) { SG_ERR_CHECK( SG_string__append__sz(pCtx, content, next) ); break; } SG_ERR_CHECK( SG_string__append__buf_len(pCtx, content, (const SG_byte *)next, (delim - next) * sizeof(char)) ); SG_ERR_CHECK( SG_string__clear(pCtx, piece) ); SG_ERR_CHECK( SG_string__clear(pCtx, replacement) ); SG_ERR_CHECK( SG_string__append__buf_len(pCtx, piece, (const SG_byte *)rest, (end - rest) * sizeof(char)) ); SG_ERR_CHECK( SG_string__append__string(pCtx, replacement, piece) ); if (SG_string__sz(piece)[0] == '<') { SG_string__remove(pCtx, piece, 0, 1); SG_ASSERT(inclusion == NULL); SG_ERR_CHECK( _read_template_file(pCtx, SG_string__sz(piece), &inclusion, pRequestHeaders, replacer) ); SG_STRING_NULLFREE(pCtx, replacement); replacement = inclusion; inclusion = NULL; } else { SG_bool needEncoding = SG_TRUE; SG_ERR_CHECK( replacer(pCtx, pRequestHeaders, piece, replaceRaw) ); // no verb-specific replacement? try generics if (sgeq(piece, replacement)) { SG_ERR_CHECK( _default_replacer(pCtx, pRequestHeaders, piece, replaceRaw, &needEncoding) ); } if (needEncoding) SG_ERR_CHECK( SG_htmlencode(pCtx, replaceRaw, replacement) ); else SG_ERR_CHECK( SG_string__set__string(pCtx, replacement, replaceRaw) ); } SG_ERR_CHECK( SG_string__append__string(pCtx, content, replacement) ); next = end + 3; } } fail: SG_STRING_NULLFREE(pCtx, instr); SG_STRING_NULLFREE(pCtx, piece); SG_STRING_NULLFREE(pCtx, replacement); SG_STRING_NULLFREE(pCtx, replaceRaw); SG_STRING_NULLFREE(pCtx, inclusion); }