http-over-capnp.capnp (7593B)
1 # Copyright (c) 2019 Cloudflare, Inc. and contributors 2 # Licensed under the MIT License: 3 # 4 # Permission is hereby granted, free of charge, to any person obtaining a copy 5 # of this software and associated documentation files (the "Software"), to deal 6 # in the Software without restriction, including without limitation the rights 7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 # copies of the Software, and to permit persons to whom the Software is 9 # furnished to do so, subject to the following conditions: 10 # 11 # The above copyright notice and this permission notice shall be included in 12 # all copies or substantial portions of the Software. 13 # 14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 # THE SOFTWARE. 21 22 @0xb665280aaff2e632; 23 # Cap'n Proto interface for HTTP. 24 25 using import "byte-stream.capnp".ByteStream; 26 27 $import "/capnp/c++.capnp".namespace("capnp"); 28 29 interface HttpService { 30 startRequest @0 (request :HttpRequest, context :ClientRequestContext) 31 -> (requestBody :ByteStream, context :ServerRequestContext); 32 # Begin an HTTP request. 33 # 34 # The client sends the request method/url/headers. The server responds with a `ByteStream` where 35 # the client can make calls to stream up the request body. `requestBody` will be null in the case 36 # that request.bodySize.fixed == 0. 37 38 interface ClientRequestContext { 39 # Provides callbacks for the server to send the response. 40 41 startResponse @0 (response :HttpResponse) -> (body :ByteStream); 42 # Server calls this method to send the response status and headers and to begin streaming the 43 # response body. `body` will be null in the case that response.bodySize.fixed == 0, which is 44 # required for HEAD responses and status codes 204, 205, and 304. 45 46 startWebSocket @1 (headers :List(HttpHeader), upSocket :WebSocket) 47 -> (downSocket :WebSocket); 48 # Server calls this method to indicate that the request is a valid WebSocket handshake and it 49 # wishes to accept it as a WebSocket. 50 # 51 # Client -> Server WebSocket frames will be sent via method calls on `upSocket`, while 52 # Server -> Client will be sent as calls to `downSocket`. 53 } 54 55 interface ServerRequestContext { 56 # Represents execution of a particular request on the server side. 57 # 58 # Dropping this object before the request completes will cancel the request. 59 # 60 # ServerRequestContext is always a promise capability. The client must wait for it to 61 # resolve using whenMoreResolved() in order to find out when the server is really done 62 # processing the request. This will throw an exception if the server failed in some way that 63 # could not be captured in the HTTP response. Note that it's possible for such an exception to 64 # be thrown even after the response body has been completely transmitted. 65 } 66 } 67 68 interface WebSocket { 69 sendText @0 (text :Text) -> stream; 70 sendData @1 (data :Data) -> stream; 71 # Send a text or data frame. 72 73 close @2 (code :UInt16, reason :Text); 74 # Send a close frame. 75 } 76 77 struct HttpRequest { 78 # Standard HTTP request metadata. 79 80 method @0 :HttpMethod; 81 url @1 :Text; 82 headers @2 :List(HttpHeader); 83 bodySize :union { 84 unknown @3 :Void; # e.g. due to transfer-encoding: chunked 85 fixed @4 :UInt64; # e.g. due to content-length 86 } 87 } 88 89 struct HttpResponse { 90 # Standard HTTP response metadata. 91 92 statusCode @0 :UInt16; 93 statusText @1 :Text; # leave null if it matches the default for statusCode 94 headers @2 :List(HttpHeader); 95 bodySize :union { 96 unknown @3 :Void; # e.g. due to transfer-encoding: chunked 97 fixed @4 :UInt64; # e.g. due to content-length 98 } 99 } 100 101 enum HttpMethod { 102 # This enum aligns precisely with the kj::HttpMethod enum. However, the backwards-compat 103 # constraints of a public-facing C++ enum vs. an internal Cap'n Proto interface differ in 104 # several ways, which could possibly lead to divergence someday. For now, a unit test verifies 105 # that they match exactly; if that test ever fails, we'll have to figure out what to do about it. 106 107 get @0; 108 head @1; 109 post @2; 110 put @3; 111 delete @4; 112 patch @5; 113 purge @6; 114 options @7; 115 trace @8; 116 117 copy @9; 118 lock @10; 119 mkcol @11; 120 move @12; 121 propfind @13; 122 proppatch @14; 123 search @15; 124 unlock @16; 125 acl @17; 126 127 report @18; 128 mkactivity @19; 129 checkout @20; 130 merge @21; 131 132 msearch @22; 133 notify @23; 134 subscribe @24; 135 unsubscribe @25; 136 } 137 138 annotation commonText @0x857745131db6fc83(enumerant) :Text; 139 140 enum CommonHeaderName { 141 invalid @0; 142 # Dummy to serve as default value. Should never actually appear on wire. 143 144 acceptCharset @1 $commonText("Accept-Charset"); 145 acceptEncoding @2 $commonText("Accept-Encoding"); 146 acceptLanguage @3 $commonText("Accept-Language"); 147 acceptRanges @4 $commonText("Accept-Ranges"); 148 accept @5 $commonText("Accept"); 149 accessControlAllowOrigin @6 $commonText("Access-Control-Allow-Origin"); 150 age @7 $commonText("Age"); 151 allow @8 $commonText("Allow"); 152 authorization @9 $commonText("Authorization"); 153 cacheControl @10 $commonText("Cache-Control"); 154 contentDisposition @11 $commonText("Content-Disposition"); 155 contentEncoding @12 $commonText("Content-Encoding"); 156 contentLanguage @13 $commonText("Content-Language"); 157 contentLength @14 $commonText("Content-Length"); 158 contentLocation @15 $commonText("Content-Location"); 159 contentRange @16 $commonText("Content-Range"); 160 contentType @17 $commonText("Content-Type"); 161 cookie @18 $commonText("Cookie"); 162 date @19 $commonText("Date"); 163 etag @20 $commonText("ETag"); 164 expect @21 $commonText("Expect"); 165 expires @22 $commonText("Expires"); 166 from @23 $commonText("From"); 167 host @24 $commonText("Host"); 168 ifMatch @25 $commonText("If-Match"); 169 ifModifiedSince @26 $commonText("If-Modified-Since"); 170 ifNoneMatch @27 $commonText("If-None-Match"); 171 ifRange @28 $commonText("If-Range"); 172 ifUnmodifiedSince @29 $commonText("If-Unmodified-Since"); 173 lastModified @30 $commonText("Last-Modified"); 174 link @31 $commonText("Link"); 175 location @32 $commonText("Location"); 176 maxForwards @33 $commonText("Max-Forwards"); 177 proxyAuthenticate @34 $commonText("Proxy-Authenticate"); 178 proxyAuthorization @35 $commonText("Proxy-Authorization"); 179 range @36 $commonText("Range"); 180 referer @37 $commonText("Referer"); 181 refresh @38 $commonText("Refresh"); 182 retryAfter @39 $commonText("Retry-After"); 183 server @40 $commonText("Server"); 184 setCookie @41 $commonText("Set-Cookie"); 185 strictTransportSecurity @42 $commonText("Strict-Transport-Security"); 186 transferEncoding @43 $commonText("Transfer-Encoding"); 187 userAgent @44 $commonText("User-Agent"); 188 vary @45 $commonText("Vary"); 189 via @46 $commonText("Via"); 190 wwwAuthenticate @47 $commonText("WWW-Authenticate"); 191 } 192 193 enum CommonHeaderValue { 194 invalid @0; 195 196 gzipDeflate @1 $commonText("gzip, deflate"); 197 198 # TODO(someday): "gzip, deflate" is the only common header value recognized by HPACK. 199 } 200 201 struct HttpHeader { 202 union { 203 common :group { 204 name @0 :CommonHeaderName; 205 union { 206 commonValue @1 :CommonHeaderValue; 207 value @2 :Text; 208 } 209 } 210 uncommon @3 :NameValue; 211 } 212 213 struct NameValue { 214 name @0 :Text; 215 value @1 :Text; 216 } 217 }