| 131 | } |
| 132 | |
| 133 | static void http_respond(int fd, const u8 *buf, size_t len) |
| 134 | { |
| 135 | const char *hdr; |
| 136 | char *resp; |
| 137 | |
| 138 | /* RFC-6455: |
| 139 | |
| 140 | The client's opening handshake consists of the following |
| 141 | parts. If the server, while reading the handshake, finds |
| 142 | that the client did not send a handshake that matches the |
| 143 | description below ... the server MUST stop processing the |
| 144 | client's handshake and return an HTTP response with an |
| 145 | appropriate error code (such as 400 Bad Request). |
| 146 | |
| 147 | 1. An HTTP/1.1 or higher GET request, including a "Request-URI" |
| 148 | [RFC2616] that should be interpreted as a /resource name/ |
| 149 | defined in Section 3 (or an absolute HTTP/HTTPS URI containing |
| 150 | the /resource name/). |
| 151 | |
| 152 | 2. A |Host| header field containing the server's authority. |
| 153 | |
| 154 | 3. An |Upgrade| header field containing the value "websocket", |
| 155 | treated as an ASCII case-insensitive value. |
| 156 | |
| 157 | 4. A |Connection| header field that includes the token "Upgrade", |
| 158 | treated as an ASCII case-insensitive value. |
| 159 | |
| 160 | 5. A |Sec-WebSocket-Key| header field with a base64-encoded (see |
| 161 | Section 4 of [RFC4648]) value that, when decoded, is 16 bytes in |
| 162 | length. |
| 163 | |
| 164 | 6. A |Sec-WebSocket-Version| header field, with a value of 13. |
| 165 | */ |
| 166 | hdr = get_http_hdr(tmpctx, buf, len, "Upgrade"); |
| 167 | if (!hdr || !strstr(hdr, "websocket")) |
| 168 | bad_http(fd, "Upgrade: websocket missing"); |
| 169 | hdr = get_http_hdr(tmpctx, buf, len, "Connection"); |
| 170 | if (!hdr || !strstr(hdr, "Upgrade")) |
| 171 | bad_http(fd, "Connection: Upgrade missing"); |
| 172 | hdr = get_http_hdr(tmpctx, buf, len, "Sec-WebSocket-Version"); |
| 173 | if (!hdr || !streq(hdr, "13")) |
| 174 | bad_http(fd, "Sec-WebSocket-Version: must be 13"); |
| 175 | hdr = get_http_hdr(tmpctx, buf, len, "Sec-WebSocket-Key"); |
| 176 | if (!hdr) |
| 177 | bad_http(fd, "Sec-WebSocket-Key missing"); |
| 178 | |
| 179 | resp = tal_fmt(tmpctx, |
| 180 | "HTTP/1.1 101 Switching Protocols\r\n" |
| 181 | "Upgrade: websocket\r\n" |
| 182 | "Connection: Upgrade\r\n" |
| 183 | "Sec-WebSocket-Accept: %s\r\n\r\n", |
| 184 | websocket_accept_str(tmpctx, hdr)); |
| 185 | |
| 186 | if (!write_all(fd, resp, strlen(resp))) |
| 187 | exit(0); |
| 188 | } |
| 189 | |
| 190 | static void http_upgrade(int fd) |
no test coverage detected