static int http_client_prepare(http_client *cp, const char *url, char *body_buffer, size_t body_length, char *type_buffer, size_t type_length) { http_parser_url parser_url; char *new_url; int sts; cp->body_buffer = body_buffer; cp->body_length = body_length; cp->type_buffer = type_buffer; cp->type_length = type_length; /* extract individual fields from the given URL */ http_parser_url_init(&parser_url); if ((sts = http_parser_parse_url(url, strlen(url), 0, &parser_url)) != 0) { cp->error_code = sts; return -1; } /* short-circuit if we are making a request from a connected server */ if (http_compare_source(&parser_url, url, &cp->parser_url, cp->url) == 0) return 0; http_client_disconnect(cp); if ((new_url = strdup(url)) == NULL) { cp->error_code = -ENOMEM; return -1; } free(cp->url); cp->url = new_url; cp->parser_url = parser_url; return 0; }
void request_context::finalise_header(http_parser* parser) { _current_hdr_value = nullptr; _current_hdr_name = nullptr; _current_header_object = nullptr; http_parser_url url_parser; http_parser_url_init(std::addressof(url_parser)); auto result = http_parser_parse_url(mutable_request_header().uri().data(), mutable_request_header().uri().size(), parser->method == HTTP_CONNECT, std::addressof(url_parser)); if (result) { BOOST_LOG_TRIVIAL(info) << "request_context::finalise_header - invalid url\n" << api::as_json(request_header()); throw invalid_url(request_header().uri()); } check_url_field(url_parser, mutable_request_header(), &HttpRequestHeader::QueryParts::mutable_schema, UF_SCHEMA); check_url_field(url_parser, mutable_request_header(), &HttpRequestHeader::QueryParts::mutable_host, UF_HOST); check_url_field(url_parser, mutable_request_header(), &HttpRequestHeader::QueryParts::mutable_port, UF_PORT); check_url_field(url_parser, mutable_request_header(), &HttpRequestHeader::QueryParts::mutable_path, UF_PATH); check_url_field(url_parser, mutable_request_header(), &HttpRequestHeader::QueryParts::mutable_query, UF_QUERY); check_url_field(url_parser, mutable_request_header(), &HttpRequestHeader::QueryParts::mutable_fragment, UF_FRAGMENT); check_url_field(url_parser, mutable_request_header(), &HttpRequestHeader::QueryParts::mutable_user_info, UF_USERINFO); mutable_request_header().set_method(http_method_str(static_cast<http_method>(parser->method))); mutable_request_header().set_version_major(parser->http_major); mutable_request_header().set_version_minor(parser->http_minor); _response_header->set_version_major(parser->http_major); _response_header->set_version_minor(parser->http_minor); BOOST_LOG_TRIVIAL(info) << "request_context::finalise_header - header complete:\n" << api::as_json(request_header()); }
/** * @brief Create a new non-blocking TLS/SSL connection with a given "HTTP" url */ int esp_tls_conn_http_new_async(const char *url, const esp_tls_cfg_t *cfg, esp_tls_t *tls) { /* Parse URI */ struct http_parser_url u; http_parser_url_init(&u); http_parser_parse_url(url, strlen(url), 0, &u); /* Connect to host */ return esp_tls_conn_new_async(&url[u.field_data[UF_HOST].off], u.field_data[UF_HOST].len, get_port(url, &u), cfg, tls); }
static mrb_value mrb_http_parser_parse_url(mrb_state *mrb, mrb_value self) { mrb_value uri_string; mrb_bool is_connect = FALSE; mrb_get_args(mrb, "S|b", &uri_string, &is_connect); struct http_parser_url parser; http_parser_url_init(&parser); enum http_parser_url_rcs rc = http_parser_parse_url(RSTRING_PTR(uri_string), RSTRING_LEN(uri_string), is_connect, &parser); switch (rc) { case URL_OKAY: { mrb_value argv[UF_MAX + 1]; for (int curr_url_field = 0; curr_url_field < UF_MAX; curr_url_field++) { if (parser.field_set & (1 << curr_url_field)) { if (curr_url_field == UF_PORT) { argv[curr_url_field] = mrb_fixnum_value(parser.port); } else { argv[curr_url_field] = mrb_str_substr(mrb, uri_string, parser.field_data[curr_url_field].off, parser.field_data[curr_url_field].len); } } else { argv[curr_url_field] = mrb_nil_value(); } } argv[UF_MAX] = uri_string; return mrb_obj_new(mrb, MRB_URI_PARSED, sizeof(argv) / sizeof(argv[0]), argv); } break; case MALFORMED_URL: mrb_raise(mrb, E_URI_MALFORMED, "Malformed URL"); break; case HOST_NOT_PRESENT: mrb_raise(mrb, E_URI_HOST_NOT_PRESENT, "Host not present"); break; case HOST_NOT_PARSEABLE: mrb_raise(mrb, E_URI_HOST_NOT_PARSEABLE, "Host not parseable"); break; case CONNECT_MALFORMED: mrb_raise(mrb, E_URI_CONNECT_MALFORMED, "Connect malformed"); break; case PORT_TOO_LARGE: mrb_raise(mrb, E_URI_PORT_TOO_LARGE, "Port too large"); break; } }
HTTPRequest::HTTPRequest() : m_method((http_method) -1), m_path(0), m_query(0), m_currentHeader(-1), m_headerLength(0), m_headerValue(true), m_age(millis()), m_id(__id++) { HTTP_DEBUG(" <%lu> HTTPRequest::HTTPRequest\n", m_id) http_parser_url_init(&m_urlP); // we store some headers by defult storeHeader("Host"); storeHeader("Content-Type"); storeHeader("Content-Length"); // CORS support storeHeader("Access-Control-Request-Method"); storeHeader("Access-Control-Request-Headers"); }
static int on_header_value(http_parser *pp, const char *offset, size_t length) { http_client *cp = (http_client *)pp->data; int sts; if (pmDebug & DBG_TRACE_HTTP) fprintf(stderr, "Header value: %.*s\n", (int)length, offset); if (cp->flags & F_LOCATION) { /* redirect location */ cp->flags &= ~F_LOCATION; if (pp->status_code >= 300 && pp->status_code < 400) { http_parser_url up; http_parser_url_init(&up); if ((sts = http_parser_parse_url(offset, length, 0, &up)) != 0) return sts; if ((sts = reset_url_location(offset, length, &up, &cp->url, &cp->parser_url)) < 0) { cp->error_code = -ENOMEM; return 1; } cp->flags |= sts; } } if (cp->flags & F_CONTENT_TYPE) { /* stash content-type */ cp->flags &= ~F_CONTENT_TYPE; if (cp->type_length > 0) { if (length + 1 > cp->type_length) { cp->error_code = -E2BIG; return 1; } strncpy(cp->type_buffer, offset, length); cp->type_buffer[length] = '\0'; } } return 0; }
URI& URI::parse() { http_parser_url u; http_parser_url_init(&u); const auto p = uri_str_.data(); const auto result = http_parser_parse_url(p, uri_str_.size(), 0, &u); #ifdef URI_THROW_ON_ERROR if (result not_eq 0) { std::string uri{uri_str_.begin(), uri_str_.end()}; throw URI_error{"Invalid uri: " + uri}; } #endif //< URI_THROW_ON_ERROR (void)result; scheme_ = (u.field_set & (1 << UF_SCHEMA)) ? util::sview{p + u.field_data[UF_SCHEMA].off, u.field_data[UF_SCHEMA].len} : util::sview{}; userinfo_ = (u.field_set & (1 << UF_USERINFO)) ? util::sview{p + u.field_data[UF_USERINFO].off, u.field_data[UF_USERINFO].len} : util::sview{}; host_ = (u.field_set & (1 << UF_HOST)) ? util::sview{p + u.field_data[UF_HOST].off, u.field_data[UF_HOST].len} : util::sview{}; path_ = (u.field_set & (1 << UF_PATH)) ? util::sview{p + u.field_data[UF_PATH].off, u.field_data[UF_PATH].len} : util::sview{}; query_ = (u.field_set & (1 << UF_QUERY)) ? util::sview{p + u.field_data[UF_QUERY].off, u.field_data[UF_QUERY].len} : util::sview{}; fragment_ = (u.field_set & (1 << UF_FRAGMENT)) ? util::sview{p + u.field_data[UF_FRAGMENT].off, u.field_data[UF_FRAGMENT].len} : util::sview{}; auto port_str_ = (u.field_set & (1 << UF_PORT)) ? util::sview{p + u.field_data[UF_PORT].off, u.field_data[UF_PORT].len} : util::sview{}; if(not port_str_.empty()) { std::array<char, 32> buf; std::copy(port_str_.begin(), port_str_.end(), buf.begin()); buf[port_str_.size()] = 0; port_ = std::atoi(buf.data()); } else { port_ = bind_port(scheme_, u.port); } return *this; }
int main(int argc, char **argv) { struct http_parser_url u; int len, connect, result; if (argc != 3) { printf("Syntax : %s connect|get url\n", argv[0]); return 1; } len = strlen(argv[2]); connect = strcmp("connect", argv[1]) == 0 ? 1 : 0; printf("Parsing %s, connect %d\n", argv[2], connect); http_parser_url_init(&u); result = http_parser_parse_url(argv[2], len, connect, &u); if (result != 0) { printf("Parse error : %d\n", result); return result; } printf("Parse ok, result : \n"); dump_url(argv[2], &u); return 0; }
void reset() noexcept { http_parser_url_init(&parser_); }
BasicUrl() noexcept { http_parser_url_init(&parser_); }