From e563bf1a35b69dd0778777a514bcb10017a92a41 Mon Sep 17 00:00:00 2001 From: Maximilian Haupt Date: Fri, 8 Sep 2017 23:14:15 +0200 Subject: [PATCH] Add support for WebDAV http methods For details about the methods see: http://www.webdav.org/specs/rfc2518.html https://en.wikipedia.org/wiki/WebDAV --- include/httpp/http/Protocol.hpp | 24 ++++++--- src/httpp/http/Parser.cpp | 79 ++++++++++++++++++++++++++-- src/httpp/http/client/Connection.cpp | 7 +++ src/httpp/http/parser.rl | 2 +- 4 files changed, 100 insertions(+), 12 deletions(-) diff --git a/include/httpp/http/Protocol.hpp b/include/httpp/http/Protocol.hpp index 4110906..9e67dd3 100644 --- a/include/httpp/http/Protocol.hpp +++ b/include/httpp/http/Protocol.hpp @@ -38,14 +38,22 @@ static char const HEADER_BODY_SEP[] = { '\r', '\n', '\r', '\n' }; enum class Method { - HEAD , - GET , - POST , - PUT , - DELETE_ , // '_' for msvc workaround - OPTIONS , - TRACE , - CONNECT + HEAD, + GET, + POST, + PUT, + DELETE_, // '_' for msvc workaround + OPTIONS, + TRACE, + CONNECT, + // WebDAV specific methods + PROPFIND, + PROPPATCH, + MKCOL, + COPY, + MOVE, + LOCK, + UNLOCK, }; std::string to_string(Method method); diff --git a/src/httpp/http/Parser.cpp b/src/httpp/http/Parser.cpp index 95613ae..2a5eaf0 100644 --- a/src/httpp/http/Parser.cpp +++ b/src/httpp/http/Parser.cpp @@ -101,6 +101,30 @@ static bool parse_method(Iterator& it, Request& request) return true; } } + else if (*it == 'R') + { + if (!expect(it, "ROP")) + { + return false; + } + + if (*it == 'F') + { + if (expect(it, "FIND")) + { + request.method = Method::PROPFIND; + return true; + } + } + else if (*it == 'P') + { + if (expect(it, "PATCH")) + { + request.method = Method::PROPPATCH; + return true; + } + } + } break; case 'D': if (expect(it, "DELETE")) @@ -123,11 +147,60 @@ static bool parse_method(Iterator& it, Request& request) return true; } break; - + case 'M': + ++it; + if (*it == 'O') + { + if (expect(it, "OVE")) + { + request.method = Method::MOVE; + return true; + } + } + else if (*it == 'K') + { + if (expect(it, "KCOL")) + { + request.method = Method::MKCOL; + return true; + } + } + break; case 'C': - if (expect(it, "CONNECT")) + ++it; + if (*it != 'O') + { + return false; + } + ++it; + if (*it == 'N') + { + if (expect(it, "NNECT")) + { + request.method = Method::CONNECT; + return true; + } + } + else if (*it == 'P') + { + if (expect(it, "PY")) + { + request.method = Method::COPY; + return true; + } + } + break; + case 'L': + if (expect(it, "LOCK")) + { + request.method = Method::LOCK; + return true; + } + break; + case 'U': + if (expect(it, "UNLOCK")) { - request.method = Method::CONNECT; + request.method = Method::UNLOCK; return true; } break; diff --git a/src/httpp/http/client/Connection.cpp b/src/httpp/http/client/Connection.cpp index acca028..3fc3ac7 100644 --- a/src/httpp/http/client/Connection.cpp +++ b/src/httpp/http/client/Connection.cpp @@ -253,6 +253,13 @@ void Connection::configureRequest(HTTPP::HTTP::Method method) case HTTPP::HTTP::Method::OPTIONS: case HTTPP::HTTP::Method::TRACE: case HTTPP::HTTP::Method::CONNECT: + case HTTPP::HTTP::Method::PROPFIND: + case HTTPP::HTTP::Method::PROPPATCH: + case HTTPP::HTTP::Method::MKCOL: + case HTTPP::HTTP::Method::COPY: + case HTTPP::HTTP::Method::MOVE: + case HTTPP::HTTP::Method::LOCK: + case HTTPP::HTTP::Method::UNLOCK: std::string method_str = to_string(method); conn_setopt(CURLOPT_CUSTOMREQUEST, method_str.data()); break; diff --git a/src/httpp/http/parser.rl b/src/httpp/http/parser.rl index fe09bb3..b4c0cd5 100644 --- a/src/httpp/http/parser.rl +++ b/src/httpp/http/parser.rl @@ -110,7 +110,7 @@ bool Parser::parse(const char* start, const char *token_begin, *token_end; %%{ - method = ("GET" | "POST" | "HEAD" | "PUT" | "DELETE" | "OPTIONS" | "TRACE" | "CONNECT"); + method = ("GET" | "POST" | "HEAD" | "PUT" | "DELETE" | "OPTIONS" | "TRACE" | "CONNECT" | "PROPFIND" | "PROPPATCH" | "MKCOL" | "COPY" | "MOVE" | "LOCK" | "UNLOCK"); identifier = (alnum | '-')+;