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

Commit e557b62

Browse files
dolmenjasnell
authored andcommitted
src: support LINK/UNLINK (RFC 2068, draft-snell-link-method)
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
1 parent e01811e commit e557b62

File tree

4 files changed

+81
-12
lines changed

4 files changed

+81
-12
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,4 @@ Romain Giraud <[email protected]>
6565
Jay Satiro <[email protected]>
6666
Arne Steen <[email protected]>
6767
Kjell Schubert <[email protected]>
68+
Olivier Mengué <[email protected]>

http_parser.c

+23-12
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ size_t http_parser_execute (http_parser *parser,
965965
case 'D': parser->method = HTTP_DELETE; break;
966966
case 'G': parser->method = HTTP_GET; break;
967967
case 'H': parser->method = HTTP_HEAD; break;
968-
case 'L': parser->method = HTTP_LOCK; break;
968+
case 'L': parser->method = HTTP_LOCK; /* or LINK */ break;
969969
case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break;
970970
case 'N': parser->method = HTTP_NOTIFY; break;
971971
case 'O': parser->method = HTTP_OPTIONS; break;
@@ -975,7 +975,7 @@ size_t http_parser_execute (http_parser *parser,
975975
case 'R': parser->method = HTTP_REPORT; /* or REBIND */ break;
976976
case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break;
977977
case 'T': parser->method = HTTP_TRACE; break;
978-
case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE, UNBIND */ break;
978+
case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE, UNBIND, UNLINK */ break;
979979
default:
980980
SET_ERRNO(HPE_INVALID_METHOD);
981981
goto error;
@@ -1038,16 +1038,25 @@ size_t http_parser_execute (http_parser *parser,
10381038
SET_ERRNO(HPE_INVALID_METHOD);
10391039
goto error;
10401040
}
1041-
} else if (parser->index == 1 && parser->method == HTTP_POST) {
1042-
if (ch == 'R') {
1043-
parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */
1044-
} else if (ch == 'U') {
1045-
parser->method = HTTP_PUT; /* or HTTP_PURGE */
1046-
} else if (ch == 'A') {
1047-
parser->method = HTTP_PATCH;
1048-
} else {
1049-
SET_ERRNO(HPE_INVALID_METHOD);
1050-
goto error;
1041+
} else if (parser->index == 1) {
1042+
if (parser->method == HTTP_POST) {
1043+
if (ch == 'R') {
1044+
parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */
1045+
} else if (ch == 'U') {
1046+
parser->method = HTTP_PUT; /* or HTTP_PURGE */
1047+
} else if (ch == 'A') {
1048+
parser->method = HTTP_PATCH;
1049+
} else {
1050+
SET_ERRNO(HPE_INVALID_METHOD);
1051+
goto error;
1052+
}
1053+
} else if (parser->method == HTTP_LOCK) {
1054+
if (ch == 'I') {
1055+
parser->method = HTTP_LINK;
1056+
} else {
1057+
SET_ERRNO(HPE_INVALID_METHOD);
1058+
goto error;
1059+
}
10511060
}
10521061
} else if (parser->index == 2) {
10531062
if (parser->method == HTTP_PUT) {
@@ -1072,6 +1081,8 @@ size_t http_parser_execute (http_parser *parser,
10721081
}
10731082
} else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') {
10741083
parser->method = HTTP_PROPPATCH;
1084+
} else if (parser->index == 3 && parser->method == HTTP_UNLOCK && ch == 'I') {
1085+
parser->method = HTTP_UNLINK;
10751086
} else {
10761087
SET_ERRNO(HPE_INVALID_METHOD);
10771088
goto error;

http_parser.h

+3
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ typedef int (*http_cb) (http_parser*);
124124
XX(29, PURGE, PURGE) \
125125
/* CalDAV */ \
126126
XX(30, MKCALENDAR, MKCALENDAR) \
127+
/* RFC-2068, section 19.6.1.2 */ \
128+
XX(31, LINK, LINK) \
129+
XX(32, UNLINK, UNLINK) \
127130

128131
enum http_method
129132
{

test.c

+54
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,58 @@ const struct message requests[] =
11011101
,.body= ""
11021102
}
11031103

1104+
/* Examples from the Internet draft for LINK/UNLINK methods:
1105+
* https://tools.ietf.org/id/draft-snell-link-method-01.html#rfc.section.5
1106+
*/
1107+
1108+
#define LINK_REQUEST 40
1109+
, {.name = "link request"
1110+
,.type= HTTP_REQUEST
1111+
,.raw= "LINK /images/my_dog.jpg HTTP/1.1\r\n"
1112+
"Host: example.com\r\n"
1113+
"Link: <http://example.com/profiles/joe>; rel=\"tag\"\r\n"
1114+
"Link: <http://example.com/profiles/sally>; rel=\"tag\"\r\n"
1115+
"\r\n"
1116+
,.should_keep_alive= TRUE
1117+
,.message_complete_on_eof= FALSE
1118+
,.http_major= 1
1119+
,.http_minor= 1
1120+
,.method= HTTP_LINK
1121+
,.request_path= "/images/my_dog.jpg"
1122+
,.request_url= "/images/my_dog.jpg"
1123+
,.query_string= ""
1124+
,.fragment= ""
1125+
,.num_headers= 3
1126+
,.headers= { { "Host", "example.com" }
1127+
, { "Link", "<http://example.com/profiles/joe>; rel=\"tag\"" }
1128+
, { "Link", "<http://example.com/profiles/sally>; rel=\"tag\"" }
1129+
}
1130+
,.body= ""
1131+
}
1132+
1133+
#define UNLINK_REQUEST 41
1134+
, {.name = "link request"
1135+
,.type= HTTP_REQUEST
1136+
,.raw= "UNLINK /images/my_dog.jpg HTTP/1.1\r\n"
1137+
"Host: example.com\r\n"
1138+
"Link: <http://example.com/profiles/sally>; rel=\"tag\"\r\n"
1139+
"\r\n"
1140+
,.should_keep_alive= TRUE
1141+
,.message_complete_on_eof= FALSE
1142+
,.http_major= 1
1143+
,.http_minor= 1
1144+
,.method= HTTP_UNLINK
1145+
,.request_path= "/images/my_dog.jpg"
1146+
,.request_url= "/images/my_dog.jpg"
1147+
,.query_string= ""
1148+
,.fragment= ""
1149+
,.num_headers= 2
1150+
,.headers= { { "Host", "example.com" }
1151+
, { "Link", "<http://example.com/profiles/sally>; rel=\"tag\"" }
1152+
}
1153+
,.body= ""
1154+
}
1155+
11041156
, {.name= NULL } /* sentinel */
11051157
};
11061158

@@ -3760,6 +3812,8 @@ main (void)
37603812
"PATCH",
37613813
"PURGE",
37623814
"MKCALENDAR",
3815+
"LINK",
3816+
"UNLINK",
37633817
0 };
37643818
const char **this_method;
37653819
for (this_method = all_methods; *this_method; this_method++) {

0 commit comments

Comments
 (0)