Skip to content
This repository has been archived by the owner on Nov 6, 2022. It is now read-only.

Commit

Permalink
src: support LINK/UNLINK (RFC 2068, draft-snell-link-method)
Browse files Browse the repository at this point in the history
Add support for HTTP methods LINK and UNLINK originally defined in RFC2068
section 19.6.2.2, but with semantic added in a Internet draft.
https://tools.ietf.org/html/rfc2068#section-19.6.1.2
https://tools.ietf.org/html/draft-snell-link-method-12

Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Fedor Induty <[email protected]>
PR-URL: #267
  • Loading branch information
dolmen authored and jasnell committed Oct 26, 2015
1 parent e01811e commit e557b62
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 12 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,4 @@ Romain Giraud <[email protected]>
Jay Satiro <[email protected]>
Arne Steen <[email protected]>
Kjell Schubert <[email protected]>
Olivier Mengué <[email protected]>
35 changes: 23 additions & 12 deletions http_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,7 @@ size_t http_parser_execute (http_parser *parser,
case 'D': parser->method = HTTP_DELETE; break;
case 'G': parser->method = HTTP_GET; break;
case 'H': parser->method = HTTP_HEAD; break;
case 'L': parser->method = HTTP_LOCK; break;
case 'L': parser->method = HTTP_LOCK; /* or LINK */ break;
case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break;
case 'N': parser->method = HTTP_NOTIFY; break;
case 'O': parser->method = HTTP_OPTIONS; break;
Expand All @@ -975,7 +975,7 @@ size_t http_parser_execute (http_parser *parser,
case 'R': parser->method = HTTP_REPORT; /* or REBIND */ break;
case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break;
case 'T': parser->method = HTTP_TRACE; break;
case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE, UNBIND */ break;
case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE, UNBIND, UNLINK */ break;
default:
SET_ERRNO(HPE_INVALID_METHOD);
goto error;
Expand Down Expand Up @@ -1038,16 +1038,25 @@ size_t http_parser_execute (http_parser *parser,
SET_ERRNO(HPE_INVALID_METHOD);
goto error;
}
} else if (parser->index == 1 && parser->method == HTTP_POST) {
if (ch == 'R') {
parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */
} else if (ch == 'U') {
parser->method = HTTP_PUT; /* or HTTP_PURGE */
} else if (ch == 'A') {
parser->method = HTTP_PATCH;
} else {
SET_ERRNO(HPE_INVALID_METHOD);
goto error;
} else if (parser->index == 1) {
if (parser->method == HTTP_POST) {
if (ch == 'R') {
parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */
} else if (ch == 'U') {
parser->method = HTTP_PUT; /* or HTTP_PURGE */
} else if (ch == 'A') {
parser->method = HTTP_PATCH;
} else {
SET_ERRNO(HPE_INVALID_METHOD);
goto error;
}
} else if (parser->method == HTTP_LOCK) {
if (ch == 'I') {
parser->method = HTTP_LINK;
} else {
SET_ERRNO(HPE_INVALID_METHOD);
goto error;
}
}
} else if (parser->index == 2) {
if (parser->method == HTTP_PUT) {
Expand All @@ -1072,6 +1081,8 @@ size_t http_parser_execute (http_parser *parser,
}
} else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') {
parser->method = HTTP_PROPPATCH;
} else if (parser->index == 3 && parser->method == HTTP_UNLOCK && ch == 'I') {
parser->method = HTTP_UNLINK;
} else {
SET_ERRNO(HPE_INVALID_METHOD);
goto error;
Expand Down
3 changes: 3 additions & 0 deletions http_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ typedef int (*http_cb) (http_parser*);
XX(29, PURGE, PURGE) \
/* CalDAV */ \
XX(30, MKCALENDAR, MKCALENDAR) \
/* RFC-2068, section 19.6.1.2 */ \
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \

enum http_method
{
Expand Down
54 changes: 54 additions & 0 deletions test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,58 @@ const struct message requests[] =
,.body= ""
}

/* Examples from the Internet draft for LINK/UNLINK methods:
* https://tools.ietf.org/id/draft-snell-link-method-01.html#rfc.section.5
*/

#define LINK_REQUEST 40
, {.name = "link request"
,.type= HTTP_REQUEST
,.raw= "LINK /images/my_dog.jpg HTTP/1.1\r\n"
"Host: example.com\r\n"
"Link: <http://example.com/profiles/joe>; rel=\"tag\"\r\n"
"Link: <http://example.com/profiles/sally>; rel=\"tag\"\r\n"
"\r\n"
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.method= HTTP_LINK
,.request_path= "/images/my_dog.jpg"
,.request_url= "/images/my_dog.jpg"
,.query_string= ""
,.fragment= ""
,.num_headers= 3
,.headers= { { "Host", "example.com" }
, { "Link", "<http://example.com/profiles/joe>; rel=\"tag\"" }
, { "Link", "<http://example.com/profiles/sally>; rel=\"tag\"" }
}
,.body= ""
}

#define UNLINK_REQUEST 41
, {.name = "link request"
,.type= HTTP_REQUEST
,.raw= "UNLINK /images/my_dog.jpg HTTP/1.1\r\n"
"Host: example.com\r\n"
"Link: <http://example.com/profiles/sally>; rel=\"tag\"\r\n"
"\r\n"
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.method= HTTP_UNLINK
,.request_path= "/images/my_dog.jpg"
,.request_url= "/images/my_dog.jpg"
,.query_string= ""
,.fragment= ""
,.num_headers= 2
,.headers= { { "Host", "example.com" }
, { "Link", "<http://example.com/profiles/sally>; rel=\"tag\"" }
}
,.body= ""
}

, {.name= NULL } /* sentinel */
};

Expand Down Expand Up @@ -3760,6 +3812,8 @@ main (void)
"PATCH",
"PURGE",
"MKCALENDAR",
"LINK",
"UNLINK",
0 };
const char **this_method;
for (this_method = all_methods; *this_method; this_method++) {
Expand Down

0 comments on commit e557b62

Please sign in to comment.