Skip to content

Commit

Permalink
Merge pull request hotwired#142 from hotwired/html-header
Browse files Browse the repository at this point in the history
Restore correct Accept header for form submissions
  • Loading branch information
sstephenson authored Jan 29, 2021
2 parents 4c439b9 + 7d98260 commit a42fa94
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 33 deletions.
6 changes: 2 additions & 4 deletions src/core/drive/form_submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,14 @@ export class FormSubmission {

// Fetch request delegate

additionalHeadersForRequest(request: FetchRequest) {
const headers: FetchRequestHeaders = {}
prepareHeadersForRequest(headers: FetchRequestHeaders, request: FetchRequest) {
if (!request.isIdempotent) {
const token = getCookieValue(getMetaContent("csrf-param")) || getMetaContent("csrf-token")
if (token) {
headers["X-CSRF-Token"] = token
}
headers["Accept"] = StreamMessage.contentType
headers["Accept"] = [ StreamMessage.contentType, headers["Accept"] ].join(", ")
}
return headers
}

requestStarted(request: FetchRequest) {
Expand Down
6 changes: 3 additions & 3 deletions src/core/frames/frame_controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FrameElement, FrameElementDelegate, FrameLoadingStyle } from "../../elements/frame_element"
import { FetchMethod, FetchRequest, FetchRequestDelegate } from "../../http/fetch_request"
import { FetchMethod, FetchRequest, FetchRequestDelegate, FetchRequestHeaders } from "../../http/fetch_request"
import { FetchResponse } from "../../http/fetch_response"
import { AppearanceObserver, AppearanceObserverDelegate } from "../../observers/appearance_observer"
import { parseHTMLDocument } from "../../util"
Expand Down Expand Up @@ -124,8 +124,8 @@ export class FrameController implements AppearanceObserverDelegate, FetchRequest

// Fetch request delegate

additionalHeadersForRequest(request: FetchRequest) {
return { "Turbo-Frame": this.id }
prepareHeadersForRequest(headers: FetchRequestHeaders, request: FetchRequest) {
headers["Turbo-Frame"] = this.id
}

requestStarted(request: FetchRequest) {
Expand Down
23 changes: 11 additions & 12 deletions src/http/fetch_request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { FetchResponse } from "./fetch_response"
import { dispatch } from "../util"

export interface FetchRequestDelegate {
additionalHeadersForRequest?(request: FetchRequest): { [header: string]: string }
prepareHeadersForRequest?(headers: FetchRequestHeaders, request: FetchRequest): void
requestStarted(request: FetchRequest): void
requestPreventedHandlingResponse(request: FetchRequest, response: FetchResponse): void
requestSucceededWithResponse(request: FetchRequest, response: FetchResponse): void
Expand Down Expand Up @@ -117,23 +117,22 @@ export class FetchRequest {
}

get headers() {
return {
"Accept": "text/html, application/xhtml+xml",
...this.additionalHeaders
}
}

get additionalHeaders() {
if (typeof this.delegate.additionalHeadersForRequest == "function") {
return this.delegate.additionalHeadersForRequest(this)
} else {
return {}
const headers = { ...this.defaultHeaders }
if (typeof this.delegate.prepareHeadersForRequest == "function") {
this.delegate.prepareHeadersForRequest(headers, this)
}
return headers
}

get abortSignal() {
return this.abortController.signal
}

get defaultHeaders() {
return {
"Accept": "text/html, application/xhtml+xml"
}
}
}

function mergeFormDataEntries(url: URL, entries: [string, FormDataEntryValue][]): URL {
Expand Down
5 changes: 5 additions & 0 deletions src/tests/fixtures/stream.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
<script>Turbo.connectStreamSource(new EventSource("/__turbo/messages"))</script>
</head>
<body>
<form id="create" method="post" action="/__turbo/messages">
<input type="hidden" name="content" value="Hello world!">
<input type="hidden" name="type" value="stream">
<button type="submit">Create</button>
</form>
<div id="messages">
<div class="message">First</div>
</div>
Expand Down
12 changes: 1 addition & 11 deletions src/tests/functional/stream_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,12 @@ export class StreamTests extends FunctionalTestCase {
element = await this.querySelector(selector)
this.assert.equal(await element.getVisibleText(), "First")

await this.createMessage("Hello world!")
await this.clickSelector("#create [type=submit]")
await this.nextBeat

element = await this.querySelector(selector)
this.assert.equal(await element.getVisibleText(), "Hello world!")
}

async createMessage(content: string) {
return this.post("/__turbo/messages", { content })
}

async post(path: string, params: any = {}) {
await this.evaluate((path, method, params) => {
fetch(location.origin + path, { method, body: new URLSearchParams(params) })
}, path, "POST", params)
}
}

StreamTests.registerSuite()
18 changes: 15 additions & 3 deletions src/tests/server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Response, Router } from "express"
import { Request, Response, Router } from "express"
import multer from "multer"
import path from "path"
import url from "url"
Expand All @@ -8,6 +8,14 @@ const streamResponses: Set<Response> = new Set

router.use(multer().none())

router.use((request, response, next) => {
if (request.accepts(["text/html", "application/xhtml+xml"])) {
next()
} else {
response.sendStatus(422)
}
})

router.post("/redirect", (request, response) => {
const { path, ...query } = request.body
const pathname = path ?? "/src/tests/fixtures/one.html"
Expand Down Expand Up @@ -39,7 +47,7 @@ router.post("/messages", (request, response) => {
const { content, status, type } = request.body
if (typeof content == "string") {
receiveMessage(content)
if (type == "stream") {
if (type == "stream" && acceptsStreams(request)) {
response.type("text/vnd.turbo-stream.html; charset=utf-8")
response.send(renderMessage(content))
} else {
Expand All @@ -55,7 +63,7 @@ router.put("/messages/:id", (request, response) => {
const { id } = request.params
if (typeof content == "string") {
receiveMessage(content)
if (type == "stream") {
if (type == "stream" && acceptsStreams(request)) {
response.type("text/vnd.turbo-stream.html; charset=utf-8")
response.send(renderMessage(id + ": " + content))
} else {
Expand Down Expand Up @@ -99,6 +107,10 @@ function renderMessage(content: string) {
`
}

function acceptsStreams(request: Request): boolean {
return !!request.accepts("text/vnd.turbo-stream.html")
}

function renderSSEData(data: any) {
return `${data}`.split("\n").map(line => "data:" + line).join("\n") + "\n\n"
}
Expand Down

0 comments on commit a42fa94

Please sign in to comment.