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()); }
void parse(bool isConnect = false) { const auto rc = http_parser_parse_url(url().data(), url().size(), isConnect ? 1 : 0, &parser_); if (rc != 0) { throw ParseException{errMsg() << "invalid url: " << url()}; } }
static int on_url(http_parser* p, const char* data, size_t length) { DataDecoder* decoder = (DataDecoder*) p->data; CHECK_NOTNULL(decoder->request); decoder->request->url.append(data, length); int result = 0; #if (HTTP_PARSER_VERSION_MAJOR >= 2) // Reworked parsing for version >= 2.0. http_parser_url url; result = http_parser_parse_url(data, length, 0, &url); if (result == 0) { if (url.field_set & (1 << UF_PATH)) { decoder->request->path.append( data + url.field_data[UF_PATH].off, url.field_data[UF_PATH].len); } if (url.field_set & (1 << UF_FRAGMENT)) { decoder->request->fragment.append( data + url.field_data[UF_FRAGMENT].off, url.field_data[UF_FRAGMENT].len); } if (url.field_set & (1 << UF_QUERY)) { decoder->query.append( data + url.field_data[UF_QUERY].off, url.field_data[UF_QUERY].len); } } #endif return result; }
int HttpTaskRunnable::headersCompleteHandler(http_parser *parser) { HttpTaskRunnable* task = static_cast<HttpTaskRunnable*>(parser->data); task->m_request->header().set(task->m_curFieldHeader, task->m_curFieldHeaderValue); task->m_request->setMethod( static_cast<Request::Method>(parser->method)); task->m_request->setVersion( QString("%1.%2").arg(parser->http_major).arg( parser->http_minor)); http_parser_url urlInfo; memset(&urlInfo, 0, sizeof(urlInfo)); int retCode = http_parser_parse_url(task->m_uri.constData(), task->m_uri.size(), parser->method == HTTP_CONNECT, &urlInfo); if (retCode == 0) { task->m_request->setUrl( extractUtr(task->m_uri.constData(), urlInfo)); } else { qDebug() << "Error parsing uri"; } return 0; }
/* based on gitno_extract_url_parts, keep c&p copy here until https://github.com/libgit2/libgit2/pull/2492 gets merged or forever ;)*/ static int extract_url_parts( char **host, char **port, char **path, char **username, char **password, const char *url, const char *default_port) { struct http_parser_url u = { 0 }; const char *_host, *_port, *_path, *_userinfo; if (http_parser_parse_url(url, strlen(url), false, &u)) { giterr_set(GITERR_NET, "Malformed URL '%s'", url); return GIT_EINVALIDSPEC; } _host = url + u.field_data[UF_HOST].off; _port = url + u.field_data[UF_PORT].off; _path = url + u.field_data[UF_PATH].off; _userinfo = url + u.field_data[UF_USERINFO].off; if (u.field_set & (1 << UF_HOST)) { *host = git__substrdup(_host, u.field_data[UF_HOST].len); GITERR_CHECK_ALLOC(*host); } if (u.field_set & (1 << UF_PORT)) { *port = git__substrdup(_port, u.field_data[UF_PORT].len); } else if (default_port) { *port = git__strdup(default_port); GITERR_CHECK_ALLOC(*port); } else { *port = NULL; } if (u.field_set & (1 << UF_PATH)) { *path = git__substrdup(_path, u.field_data[UF_PATH].len); GITERR_CHECK_ALLOC(*path); } else { giterr_set(GITERR_NET, "invalid url, missing path"); return GIT_EINVALIDSPEC; } if (u.field_set & (1 << UF_USERINFO)) { const char *colon = memchr(_userinfo, ':', u.field_data[UF_USERINFO].len); if (colon) { *username = unescape(git__substrdup(_userinfo, colon - _userinfo)); *password = unescape(git__substrdup(colon + 1, u.field_data[UF_USERINFO].len - (colon + 1 - _userinfo))); GITERR_CHECK_ALLOC(*password); } else { *username = git__substrdup(_userinfo, u.field_data[UF_USERINFO].len); } GITERR_CHECK_ALLOC(*username); } return 0; }
static int32_t request_url_cb(http_parser *p, const char *buf, size_t len) { struct turbo_parser_wrapper *nw = (struct turbo_parser_wrapper*)p->data; nw->url_str = buf; nw->url_sz = len; nw->url_rc = http_parser_parse_url(buf, len, 0, &nw->url); return 0; }
/* * Handle absolute and relative URL locations (redirects). * If it is relative, we need to preserve the original URL * schema/host/port component. */ static int reset_url_location(const char *tourl, size_t tolen, http_parser_url *top, char **fromurl, http_parser_url *fromp) { http_parser_url *cp = fromp; char *curl = *fromurl; const char *suffix; char *url, *str; int size, bytes, length; int flags = F_REDIRECTED; /* if relative location, stay connected and fast-track it */ length = top->field_data[UF_SCHEMA].len + top->field_data[UF_HOST].len; if (length == 0) { /* build URL with host, schema, port from original */ if ((bytes = cp->field_data[UF_PATH].off) == 0) bytes = strlen(curl); length = (tolen - top->field_data[UF_PATH].off); suffix = (tourl + top->field_data[UF_PATH].off); size = bytes + length + 2; /* separator + terminator */ if ((url = malloc(size)) == NULL) return -ENOMEM; strncpy(url, curl, bytes); str = url + bytes; if (*suffix != '/') *str++ = '/'; strncat(str, suffix, length); url[size - 1] = '\0'; http_parser_parse_url(url, size, 0, fromp); if (pmDebug & DBG_TRACE_HTTP) fprintf(stderr, "Redirecting from '%s' to '%s'\n", curl, url); free(curl); *fromurl = url; return flags; } /* * Redirecting to absolute locations life is simpler. However * if we have a new/different schema/host/port flag that so we * can avoid the teardown/reconnect to the same server later. */ bytes = top->field_data[UF_HOST].len; if (cp->field_data[UF_HOST].len != bytes) flags |= F_DISCONNECT; else if (strncmp(tourl + top->field_data[UF_HOST].off, curl + cp->field_data[UF_HOST].off, bytes) != 0) flags |= F_DISCONNECT; if (top->port == 0) top->port = HTTP_PORT; if (top->port != cp->port) flags |= F_DISCONNECT; *fromurl = (char *)tourl; *fromp = *top; return flags; }
int onUrl(http_parser *parser, const char *p,size_t len) { QByteArray buffer(p,len); //qDebug()<<"onUrl:"<<QString(buffer); static_cast<TcpSocket*>(parser->data)->getHeader().setUrl(QString(buffer)); http_parser_url *u = static_cast<http_parser_url*>(malloc(sizeof(http_parser_url))); http_parser_parse_url(p,len,1,u); if (u->field_set & (1 << UF_SCHEMA)) { QString string(QByteArray(&p[u->field_data[UF_SCHEMA].off], u->field_data[UF_SCHEMA].len)); //qDebug() << "UF_SCHEMA" << string; } if (u->field_set & (1 << UF_HOST)) { QString string(QByteArray(&p[u->field_data[UF_HOST].off], u->field_data[UF_HOST].len)); //qDebug() << "UF_HOST" << string; } if (u->field_set & (1 << UF_PORT)) { QString string(QByteArray(&p[u->field_data[UF_PORT].off], u->field_data[UF_PORT].len)); //qDebug() << "UF_PORT" << string; } if (u->field_set & (1<<UF_PATH)) { QString string(QByteArray(&p[u->field_data[UF_PATH].off], u->field_data[UF_PATH].len)); static_cast<TcpSocket*>(parser->data)->getHeader().setPath(string); //qDebug() << "UF_PATH" << string; } if (u->field_set & (1<<UF_QUERY)) { QString string(QByteArray(&p[u->field_data[UF_QUERY].off], u->field_data[UF_QUERY].len)); static_cast<TcpSocket*>(parser->data)->getHeader().setQueryString(string); //qDebug() << "UF_QUERY" << string; } if (u->field_set & (1<<UF_FRAGMENT)) { QString string(QByteArray(&p[u->field_data[UF_FRAGMENT].off], u->field_data[UF_FRAGMENT].len)); //qDebug() << "UF_FRAGMENT" << string; } if (u->field_set & (1<<UF_USERINFO)) { QString string(QByteArray(&p[u->field_data[UF_USERINFO].off], u->field_data[UF_USERINFO].len)); //qDebug() << "UF_USERINFO" << string; } free(u); return 0; }
void UrlObject::parse(const char *buf, std::size_t len, bool is_connect) { // TODO: validate input parameters _buf = std::string(buf, len); if (http_parser_parse_url(buf, len, is_connect, &_handle) != 0) { // failed for some reason // TODO: let the caller know the Error code (or Error message) throw UrlParseException(); } }
int parse_url(const char *url, struct http_parser_url *u, http_request *request) { if (url == NULL) { return -1; } char real_url[1024] = {0}; if ((is_match_pattern(url, REGEX_URL_SCHEME)) != 0) { snprintf(real_url, 1024, "http://%s", url); } else { snprintf(real_url, 1024, "%s", url); } SCREEN(SCREEN_YELLOW, stdout, "Request url:\t\t"); SCREEN(SCREEN_DARK_GREEN, stdout, "%s\n", real_url); int url_len = strlen(real_url); int ret = http_parser_parse_url(real_url, url_len, 0, u); if (ret != 0) { printf("Invalid request url!\n"); return -1; } char strport[64] = {0}; for (unsigned i = 0; i < UF_MAX; i++) { if ((u->field_set & (1 << i)) == 0) { continue; } switch (i) { case UF_SCHEMA: snprintf(request->scheme, 16, "%.*s", u->field_data[i].len, real_url + u->field_data[i].off); break; case UF_HOST: snprintf(request->host, 256, "%.*s", u->field_data[i].len, real_url + u->field_data[i].off); break; case UF_PORT: snprintf(strport, 64, "%.*s", u->field_data[i].len, real_url + u->field_data[i].off); request->port = atoi(strport); break; case UF_PATH: snprintf(request->path, 256, "%.*s", u->field_data[i].len, real_url + u->field_data[i].off); break; case UF_QUERY: snprintf(request->querystring, 1024, "%.*s", u->field_data[i].len, real_url + u->field_data[i].off); break; case UF_FRAGMENT: snprintf(request->fragment, 256, "%.*s", u->field_data[i].len, real_url + u->field_data[i].off); break; case UF_USERINFO: snprintf(request->userinfo, 256, "%.*s", u->field_data[i].len, real_url + u->field_data[i].off); break; default: break; } } return 0; }
static int _parse_url(shttp_connection_internal_t* conn) { struct http_parser_url parse_url; int rc; cstring_t data; data.str = conn_incomming(conn).url.str; data.len = conn_incomming(conn).url.len; rc = http_parser_parse_url(conn_incomming(conn).url.str, conn_incomming(conn).url.len, (HTTP_CONNECT == conn->parser.method)? 1:0, &parse_url); if(0 != rc) { ERR("parse_url: style error\n"); return -1; } #define http_uri conn_request(conn).uri sstring_init(http_uri.full, data.str, data.len); sstring_init(http_uri.schema, data.str + parse_url.field_data[UF_SCHEMA].off, parse_url.field_data[UF_SCHEMA].len); sstring_init(http_uri.host, data.str + parse_url.field_data[UF_HOST].off, parse_url.field_data[UF_HOST].len); sstring_init(http_uri.port_s, data.str + parse_url.field_data[UF_PORT].off, parse_url.field_data[UF_PORT].len); http_uri.port_i = parse_url.port; sstring_init(http_uri.path, data.str + parse_url.field_data[UF_PATH].off, parse_url.field_data[UF_PATH].len); sstring_init(http_uri.query, data.str + parse_url.field_data[UF_QUERY].off, parse_url.field_data[UF_QUERY].len); sstring_init(http_uri.fragment, data.str + parse_url.field_data[UF_FRAGMENT].off, parse_url.field_data[UF_FRAGMENT].len); sstring_init(http_uri.user_info, data.str + parse_url.field_data[UF_USERINFO].off, parse_url.field_data[UF_USERINFO].len); return 0; //return incomming->callbacks->on_message_begin(incomming->conn, // incomming->parser.http_major, // incomming->parser.http_minor, // incomming->parser.method, // &uri); }
bool URL::parse(const std::string& url, bool whiny) { DebugL << "Parsing: " << url << std::endl; _buf = url; if (http_parser_parse_url(url.c_str(), url.length(), 0, &_parser) == 0) return true; _buf.clear(); if (whiny) throw std::runtime_error("Syntax error: Cannot parse invalid URL: " + url); return false; }
/** * @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); }
void HttpRequest::parseUrl() { if(!schema.empty()) { return; } struct http_parser_url u; if(http_parser_parse_url(url.c_str(), url.size(), 0, &u) != 0) { LOG_ERROR("parseurl error %s", url.c_str()); return; } if(u.field_set & (1 << UF_SCHEMA)) { schema = url.substr(u.field_data[UF_SCHEMA].off, u.field_data[UF_SCHEMA].len); } if(u.field_set & (1 << UF_HOST)) { host = url.substr(u.field_data[UF_HOST].off, u.field_data[UF_HOST].len); } if(u.field_set & (1 << UF_PORT)) { port = u.port; } else { if(strcasecmp(schema.c_str(), "https") == 0 || strcasecmp(schema.c_str(), "wss") == 0) { port = 443; } else { port = 80; } } if(u.field_set & (1 << UF_PATH)) { path = url.substr(u.field_data[UF_PATH].off, u.field_data[UF_PATH].len); } if(u.field_set & (1 << UF_QUERY)) { query = url.substr(u.field_data[UF_QUERY].off, u.field_data[UF_QUERY].len); parseQuery(); } }
static int parser_settings_on_url(http_parser* parser, const char *at, size_t len) { mrb_http_parser_context *context = (mrb_http_parser_context*) parser->data; mrb_state* mrb = context->mrb; if(http_parser_parse_url(at, len, FALSE, &context->handle) != 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } mrb_iv_set(mrb, context->instance, mrb_intern(mrb, "buf"), mrb_str_new(mrb, at, len)); return 0; }
bool URL::parse(const std::string& url, bool whiny) { LTrace("Parsing: ", url) std::string src(util::trim(url)); _buf = src; if (http_parser_parse_url(src.c_str(), src.length(), 0, &_parser) == 0) return true; _buf.clear(); if (whiny) throw std::runtime_error("Syntax error: Cannot parse invalid URL: " + src); return false; }
int connection::on_url(http_parser* parser, const char *at, size_t len) { connection* c = (connection*)parser->data; size_t nres = http_parser_parse_url(at, len, 0, &c->_parser_url); if (!nres) { if ((1 << UF_PATH) & c->_parser_url.field_set) c->_request._url.append(&at[c->_parser_url.field_data[UF_PATH].off], c->_parser_url.field_data[UF_PATH].len); if ((1 << UF_QUERY) & c->_parser_url.field_set) c->_request._query.append(&at[c->_parser_url.field_data[UF_QUERY].off], c->_parser_url.field_data[UF_QUERY].len); } return (int)nres; }
int HttpParser::headers_complete_cb (http_parser *p) { m_message.m_method = (http_method)p->method; m_message.m_status_code = p->status_code; m_message.m_http_major = p->http_major; m_message.m_http_minor = p->http_minor; m_message.m_headers_complete_cb_called = 1; m_message.m_should_keep_alive = http_should_keep_alive(p); int rv = http_parser_parse_url(m_message.m_request_url.c_str(), m_message.m_request_url.size(), 0, &m_message.m_http_parser_url); m_message.url_UF_SCHEMA.assign( m_message.m_request_url.c_str() + m_message.m_http_parser_url.field_data[UF_SCHEMA].off, m_message.m_http_parser_url.field_data[UF_SCHEMA].len); m_message.url_UF_HOST.assign( m_message.m_request_url.c_str() + m_message.m_http_parser_url.field_data[UF_HOST].off, m_message.m_http_parser_url.field_data[UF_HOST].len); m_message.url_UF_PORT.assign( m_message.m_request_url.c_str() + m_message.m_http_parser_url.field_data[UF_PORT].off, m_message.m_http_parser_url.field_data[UF_PORT].len); m_message.url_UF_PATH.assign( m_message.m_request_url.c_str() + m_message.m_http_parser_url.field_data[UF_PATH].off, m_message.m_http_parser_url.field_data[UF_PATH].len); m_message.url_UF_QUERY.assign( m_message.m_request_url.c_str() + m_message.m_http_parser_url.field_data[UF_QUERY].off, m_message.m_http_parser_url.field_data[UF_QUERY].len); m_message.url_UF_FRAGMENT.assign( m_message.m_request_url.c_str() + m_message.m_http_parser_url.field_data[UF_FRAGMENT].off, m_message.m_http_parser_url.field_data[UF_FRAGMENT].len); m_message.url_UF_USERINFO.assign( m_message.m_request_url.c_str() + m_message.m_http_parser_url.field_data[UF_USERINFO].off, m_message.m_http_parser_url.field_data[UF_USERINFO].len); printf("SCHEMA(%s)\n HOST(%s)\n PORT(%s)\n PATH(%s)\n QUERY(%s)\n FRAGMENT(%s)\n USERINFO(%s)\n", m_message.url_UF_SCHEMA.c_str(), m_message.url_UF_HOST.c_str(), m_message.url_UF_PORT.c_str(), m_message.url_UF_PATH.c_str(), m_message.url_UF_QUERY.c_str(), m_message.url_UF_FRAGMENT.c_str(), m_message.url_UF_USERINFO.c_str() ); rv=rv; printf("Method=%d;m_status_code=%d;http_major=%d;http_minor=%d;headers_complete_cb_called=%d;m_should_keep_alive=%d\n", m_message.m_method, m_message.m_status_code, m_message.m_http_major, m_message.m_http_minor , m_message.m_headers_complete_cb_called , m_message.m_should_keep_alive ); return 0; }
int onUrl(http_parser* , const char *at, size_t length) { assert(s_currentRequest != nullptr); s_currentRequest->url += std::string(at, length); int result = http_parser_parse_url(s_currentRequest->url.c_str(), s_currentRequest->url.length(), 0, &s_parsedUrl); if(result != 0) { logInfo() << "Cannot parse URL: " << s_currentRequest->url << "\n"; } return 0; }
void ICACHE_FLASH_ATTR http_parse_url(http_connection *c){ memset(&c->url_parsed,0,sizeof(struct http_parser_url)); http_parser_parse_url( (const char *)c->url, strlen(c->url), 0, &c->url_parsed ); #ifdef DEVELOP_VERSION NODE_DBG("Parse URL : %s",c->url); NODE_DBG("\tPORT: %d",c->url_parsed.port); if(c->url_parsed.field_set & (1<<UF_SCHEMA)){ NODE_DBG("\tSCHEMA: "); nprintf(c->url + c->url_parsed.field_data[UF_SCHEMA].off,c->url_parsed.field_data[UF_SCHEMA].len); } if(c->url_parsed.field_set & (1<<UF_HOST)){ NODE_DBG("\tHOST: "); nprintf(c->url + c->url_parsed.field_data[UF_HOST].off,c->url_parsed.field_data[UF_HOST].len); } if(c->url_parsed.field_set & (1<<UF_PORT)){ NODE_DBG("\tPORT: "); nprintf(c->url + c->url_parsed.field_data[UF_PORT].off,c->url_parsed.field_data[UF_PORT].len); } if(c->url_parsed.field_set & (1<<UF_PATH)){ NODE_DBG("\tPATH: "); nprintf(c->url + c->url_parsed.field_data[UF_PATH].off,c->url_parsed.field_data[UF_PATH].len); } if(c->url_parsed.field_set & (1<<UF_QUERY)){ NODE_DBG("\tQUERY: "); nprintf(c->url + c->url_parsed.field_data[UF_QUERY].off,c->url_parsed.field_data[UF_QUERY].len); } if(c->url_parsed.field_set & (1<<UF_FRAGMENT)){ NODE_DBG("\tFRAGMENT: "); nprintf(c->url + c->url_parsed.field_data[UF_FRAGMENT].off,c->url_parsed.field_data[UF_FRAGMENT].len); } if(c->url_parsed.field_set & (1<<UF_USERINFO)){ NODE_DBG("\tUSER INFO: "); nprintf(c->url + c->url_parsed.field_data[UF_USERINFO].off,c->url_parsed.field_data[UF_USERINFO].len); } #endif }
static mrb_value mrb_http_parser_parse_url(mrb_state *mrb, mrb_value self) { mrb_value c; mrb_value arg_data; struct http_parser_url handle = {0}; struct RClass* _class_http, *_class_http_url; mrb_get_args(mrb, "S", &arg_data); if (http_parser_parse_url(RSTRING_PTR(arg_data), RSTRING_LEN(arg_data), FALSE, &handle)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid URL"); } _class_http = mrb_module_get(mrb, "HTTP"); _class_http_url = mrb_class_ptr(mrb_const_get(mrb, mrb_obj_value(_class_http), mrb_intern_cstr(mrb, "URL"))); c = mrb_obj_new(mrb, _class_http_url, 0, NULL); if (handle.field_set & (1<<UF_SCHEMA)) { OBJECT_SET(mrb, c, "schema", mrb_str_substr(mrb, arg_data, handle.field_data[UF_SCHEMA].off, handle.field_data[UF_SCHEMA].len)); } if (handle.field_set & (1<<UF_HOST)) { OBJECT_SET(mrb, c, "host", mrb_str_substr(mrb, arg_data, handle.field_data[UF_HOST].off, handle.field_data[UF_HOST].len)); } if (handle.field_set & (1<<UF_HOST)) { OBJECT_SET(mrb, c, "host", mrb_str_substr(mrb, arg_data, handle.field_data[UF_HOST].off, handle.field_data[UF_HOST].len)); } if (handle.field_set & (1<<UF_PORT)) { OBJECT_SET(mrb, c, "port", mrb_fixnum_value(handle.port)); } else { if (handle.field_set & (1<<UF_SCHEMA)) { mrb_value schema = mrb_str_substr(mrb, arg_data, handle.field_data[UF_SCHEMA].off, handle.field_data[UF_SCHEMA].len); if (!mrb_nil_p(schema) && !strcmp("https", (char*) RSTRING_PTR(schema))) { OBJECT_SET(mrb, c, "port", mrb_fixnum_value(443)); } } } if (handle.field_set & (1<<UF_PATH)) { OBJECT_SET(mrb, c, "path", mrb_str_substr(mrb, arg_data, handle.field_data[UF_PATH].off, handle.field_data[UF_PATH].len)); } if (handle.field_set & (1<<UF_QUERY)) { OBJECT_SET(mrb, c, "query", mrb_str_substr(mrb, arg_data, handle.field_data[UF_QUERY].off, handle.field_data[UF_QUERY].len)); } if (handle.field_set & (1<<UF_FRAGMENT)) { OBJECT_SET(mrb, c, "fragment", mrb_str_substr(mrb, arg_data, handle.field_data[UF_FRAGMENT].off, handle.field_data[UF_FRAGMENT].len)); } return c; }
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; } }
static int on_url(http_parser* parser, const char* at, size_t length) { evweb_http_processer* processer = (evweb_http_processer*)parser; size_t current_len = processer->request.url_length; print_debug("url received: %.*s\n", (int)length, at); processer->request.url_length += length; processer->request.url = realloc(processer->request.url, processer->request.url_length + 1); if (NULL == processer->request.url) { print_err("failed to realloc memory for the url: %s\n", strerror(errno)); return 1; } memcpy(processer->request.url + current_len, at, length); processer->request.url[processer->request.url_length] = '\0'; return http_parser_parse_url(processer->request.url, processer->request.url_length, 0, &(processer->request.parsed_url_info)); }
int main(int argc, char ** argv) { if (argc != 3) { printf("Syntax : %s connect|get url\n", argv[0]); return 1; } struct http_parser_url u; int len = strlen(argv[2]); int connect = strcmp("connect", argv[1]) == 0 ? 1 : 0; printf("Parsing %s, connect %d\n", argv[2], connect); int 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; }
int QHttpConnection::HeadersComplete(http_parser *parser) { QHttpConnection *theConnection = static_cast<QHttpConnection *>(parser->data); Q_ASSERT(theConnection->m_request); /** set method **/ theConnection->m_request->setMethod(static_cast<QHttpRequest::HttpMethod>(parser->method)); /** set version **/ theConnection->m_request->setVersion( QString("%1.%2").arg(parser->http_major).arg(parser->http_minor)); /** get parsed url **/ struct http_parser_url urlInfo; int r = http_parser_parse_url(theConnection->m_currentUrl.constData(), theConnection->m_currentUrl.size(), parser->method == HTTP_CONNECT, &urlInfo); Q_ASSERT(r == 0); Q_UNUSED(r); theConnection->m_request->setUrl(createUrl(theConnection->m_currentUrl.constData(), urlInfo)); // Insert last remaining header theConnection->m_currentHeaders[theConnection->m_currentHeaderField.toLower()] = theConnection->m_currentHeaderValue; theConnection->m_request->setHeaders(theConnection->m_currentHeaders); /** set client information **/ theConnection->m_request->m_remoteAddress = theConnection->m_socket->peerAddress().toString(); theConnection->m_request->m_remotePort = theConnection->m_socket->peerPort(); QHttpResponse *response = new QHttpResponse(theConnection); if (parser->http_major < 1 || parser->http_minor < 1) response->m_keepAlive = false; connect(theConnection, SIGNAL(destroyed()), response, SLOT(connectionClosed())); connect(response, SIGNAL(done()), theConnection, SLOT(responseDone())); // we are good to go! emit theConnection->newRequest(theConnection->m_request, response); return 0; }
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; }
int MUrl::parse() { http_parser_url hpu; if (http_parser_parse_url(m_url.c_str(), m_url.length(), 0, &hpu) != 0) { return -1; } m_scheme = getUrlField(m_url, UF_SCHEMA, hpu); m_host = getUrlField(m_url, UF_HOST, hpu); m_port = getUrlField(m_url, UF_PORT, hpu).toShort(); m_path = getUrlField(m_url, UF_PATH, hpu); m_query = getUrlField(m_url, UF_QUERY, hpu); m_fragment = getUrlField(m_url, UF_FRAGMENT, hpu); if (hasQuery()) { parseQuery(); } return 0; }
void ParseURL::parse() noexcept { if (validateScheme(url_)) { struct http_parser_url u; memset(&u, 0, sizeof(struct http_parser_url)); // init before used valid_ = !(http_parser_parse_url(url_.data(), url_.size(), 0, &u)); if(valid_) { // Since we init the http_parser_url with all fields to 0, if the field // not present in url, it would be [0, 0], means that this field starts at // 0 and len = 0, we will get "" from this. So no need to check field_set // before get field. scheme_ = url_.subpiece(u.field_data[UF_SCHEMA].off, u.field_data[UF_SCHEMA].len); if(u.field_data[UF_HOST].off != 0 && url_[u.field_data[UF_HOST].off - 1] == '[') { // special case: host: [::1] host_ = url_.subpiece(u.field_data[UF_HOST].off - 1, u.field_data[UF_HOST].len + 2); } else { host_ = url_.subpiece(u.field_data[UF_HOST].off, u.field_data[UF_HOST].len); } port_ = u.port; path_ = url_.subpiece(u.field_data[UF_PATH].off, u.field_data[UF_PATH].len); query_ = url_.subpiece(u.field_data[UF_QUERY].off, u.field_data[UF_QUERY].len); fragment_ = url_.subpiece(u.field_data[UF_FRAGMENT].off, u.field_data[UF_FRAGMENT].len); authority_ = (port_) ? folly::to<std::string>(host_, ":", port_) : host_.str(); } } else { parseNonFully(); } }
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; }