Bug 1646027 - Request mimeType should be sent on response start. r=Honza,bomsy,devtools-backward-compat-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D82206
This commit is contained in:
Farooq AR 2020-07-08 09:42:44 +00:00
Родитель 1ad6fbabbc
Коммит ec6505b9a1
12 изменённых файлов: 54 добавлений и 66 удалений

Просмотреть файл

@ -18,9 +18,6 @@ class EventSourceFront extends FrontClassWithSpec(eventSourceSpec) {
constructor(client, targetFront, parentFront) {
super(client, targetFront, parentFront);
this._onEventSourceConnectionOpened = this._onEventSourceConnectionOpened.bind(
this
);
this._onEventSourceConnectionClosed = this._onEventSourceConnectionClosed.bind(
this
);
@ -30,10 +27,6 @@ class EventSourceFront extends FrontClassWithSpec(eventSourceSpec) {
// out of the target actor's form
this.formAttributeName = "eventSourceActor";
this.on(
"serverEventSourceConnectionOpened",
this._onEventSourceConnectionOpened
);
this.on(
"serverEventSourceConnectionClosed",
this._onEventSourceConnectionClosed
@ -45,24 +38,11 @@ class EventSourceFront extends FrontClassWithSpec(eventSourceSpec) {
* Close the EventSourceFront.
*/
destroy() {
this.off("serverEventSourceConnectionOpened");
this.off("serverEventSourceConnectionClosed");
this.off("serverEventReceived");
return super.destroy();
}
/**
* The "eventSourceConnectionOpened" message type handler. We redirect any
* message to the UI for displaying.
*
* @private
* @param number httpChannelId
* Channel ID of the eventsource connection.
*/
async _onEventSourceConnectionOpened(httpChannelId) {
this.emit("eventSourceConnectionOpened", httpChannelId);
}
/**
* The "eventSourceConnectionClosed" message type handler. We redirect any message to
* the UI for displaying.

Просмотреть файл

@ -143,6 +143,7 @@ class WebConsoleFront extends FrontClassWithSpec(webconsoleSpec) {
networkInfo.response.remoteAddress = packet.response.remoteAddress;
networkInfo.response.remotePort = packet.response.remotePort;
networkInfo.discardResponseBody = packet.response.discardResponseBody;
networkInfo.response.mimeType = packet.response.mimeType;
networkInfo.response.waitingTime = packet.response.waitingTime;
break;
case "responseContent":

Просмотреть файл

@ -42,12 +42,14 @@ function updateRequest(id, data, batch) {
};
}
function setEventStreamFlag(channelId) {
function setEventStreamFlag(id, batch) {
return {
type: SET_EVENT_STREAM_FLAG,
channelId,
id,
meta: { batch },
};
}
/**
* Clone request by id. Used when cloning a request
* through the "Edit and Resend" option present in the context menu.

Просмотреть файл

@ -48,7 +48,7 @@ const UPDATED_MSG_SUMMARY_PROPS = ["count", "totalMs", "totalSize"];
class StatusBar extends Component {
static get propTypes() {
return {
channelType: PropTypes.string.isRequired,
channelType: PropTypes.string,
summary: PropTypes.object.isRequired,
};
}

Просмотреть файл

@ -54,7 +54,7 @@ class Toolbar extends Component {
setMessageFilterText: PropTypes.func.isRequired,
messageFilterType: PropTypes.string.isRequired,
showControlFrames: PropTypes.bool.isRequired,
channelType: PropTypes.string.isRequired,
channelType: PropTypes.string,
};
}

Просмотреть файл

@ -197,10 +197,6 @@ class FirefoxConnector {
const eventSourceFront = await this.currentTarget.getFront("eventSource");
eventSourceFront.startListening();
eventSourceFront.on(
"eventSourceConnectionOpened",
this.dataProvider.onEventSourceConnectionOpened
);
eventSourceFront.on(
"eventSourceConnectionClosed",
this.dataProvider.onEventSourceConnectionClosed
@ -237,10 +233,6 @@ class FirefoxConnector {
const eventSourceFront = this.currentTarget.getCachedFront("eventSource");
if (eventSourceFront) {
eventSourceFront.off(
"eventSourceConnectionOpened",
this.dataProvider.onEventSourceConnectionOpened
);
eventSourceFront.off(
"eventSourceConnectionClosed",
this.dataProvider.onEventSourceConnectionClosed

Просмотреть файл

@ -56,13 +56,11 @@ class FirefoxDataProvider {
this.onFrameSent = this.onFrameSent.bind(this);
this.onFrameReceived = this.onFrameReceived.bind(this);
this.onEventSourceConnectionOpened = this.onEventSourceConnectionOpened.bind(
this
);
this.onEventSourceConnectionClosed = this.onEventSourceConnectionClosed.bind(
this
);
this.onEventReceived = this.onEventReceived.bind(this);
this.setEventStreamFlag = this.setEventStreamFlag.bind(this);
}
/**
@ -399,7 +397,7 @@ class FirefoxDataProvider {
* @param {object} packet the message received from the server.
* @param {object} networkInfo the network request information.
*/
onNetworkEventUpdate(data) {
async onNetworkEventUpdate(data) {
const { packet, networkInfo } = data;
const { actor } = networkInfo;
const { updateType } = packet;
@ -421,6 +419,12 @@ class FirefoxDataProvider {
headersSize: networkInfo.response.headersSize,
waitingTime: networkInfo.response.waitingTime,
});
// Identify the channel as SSE if mimeType is event-stream.
if (networkInfo.response.mimeType?.includes("text/event-stream")) {
await this.setEventStreamFlag(actor);
}
this.emitForTests(TEST_EVENTS.STARTED_RECEIVING_RESPONSE, actor);
break;
case "responseContent":
@ -447,7 +451,7 @@ class FirefoxDataProvider {
// and can be requested via `requestData`
this.pushRequestToQueue(actor, { [`${updateType}Available`]: true });
this.onPayloadDataReceived(actor);
await this.onPayloadDataReceived(actor);
this.emitForTests(TEST_EVENTS.NETWORK_EVENT_UPDATED, actor);
}
@ -800,14 +804,6 @@ class FirefoxDataProvider {
/**
* Handle EventSource events.
*/
async onEventSourceConnectionOpened(httpChannelId) {
// By default, an EventSource connection doesn't immediately get its mimeType, or
// any info which could help us identify a connection is an SSE channel.
// We add a new flag "isEventStream" on the request to identify an SSE channel.
if (this.actionsEnabled && this.actions.setEventStreamFlag) {
await this.actions.setEventStreamFlag(httpChannelId);
}
}
async onEventSourceConnectionClosed(httpChannelId) {
if (this.actionsEnabled && this.actions.closeConnection) {
@ -820,6 +816,12 @@ class FirefoxDataProvider {
this.addMessage(httpChannelId, data);
}
async setEventStreamFlag(actorId) {
if (this.actionsEnabled && this.actions.setEventStreamFlag) {
await this.actions.setEventStreamFlag(actorId, true);
}
}
/**
* Fire events for the owner object.
*/

Просмотреть файл

@ -75,6 +75,7 @@ function Messages(initialState = {}) {
messageDetailsOpen: false,
currentChannelId: null,
currentChannelType: null,
currentRequestId: null,
closedConnections: new Map(),
columns: getMessageDefaultColumnsState(),
...initialState,
@ -90,15 +91,21 @@ function setCurrentChannel(state, action) {
return state;
}
const { channelId, isEventStream } = action.request;
const { id, cause, channelId, isEventStream } = action.request;
const { EVENT_STREAM, WEB_SOCKET } = CHANNEL_TYPE;
const currentChannelType = isEventStream ? EVENT_STREAM : WEB_SOCKET;
let currentChannelType = null;
if (cause.type === "websocket") {
currentChannelType = WEB_SOCKET;
} else if (isEventStream) {
currentChannelType = EVENT_STREAM;
}
return {
...state,
columns: getMessageDefaultColumnsState(currentChannelType),
currentChannelId: channelId,
currentChannelType,
currentRequestId: id,
// Default filter text is empty string for a new connection
messageFilterText: "",
};
@ -106,16 +113,16 @@ function setCurrentChannel(state, action) {
/**
* If the request is already selected and isEventStream flag
* is added later, we need to update the current channel.
* is added later, we need to update currentChannelType & columns.
*/
function setEventStreamFlag(state, action) {
if (state.currentChannelId === action.channelId) {
return setCurrentChannel(state, {
request: {
channelId: action.channelId,
isEventStream: true,
},
});
function updateCurrentChannel(state, action) {
if (state.currentRequestId === action.id) {
const currentChannelType = CHANNEL_TYPE.EVENT_STREAM;
return {
...state,
columns: getMessageDefaultColumnsState(currentChannelType),
currentChannelType,
};
}
return state;
}
@ -274,7 +281,7 @@ function messages(state = Messages(), action) {
case SELECT_REQUEST:
return setCurrentChannel(state, action);
case SET_EVENT_STREAM_FLAG:
return setEventStreamFlag(state, action);
return updateCurrentChannel(state, action);
case MSG_ADD:
return addMessage(state, action);
case MSG_SELECT:

Просмотреть файл

@ -208,8 +208,8 @@ function updateRequest(state, action) {
function setEventStreamFlag(state, action) {
const { requests } = state;
const { channelId } = action;
const index = requests.findIndex(needle => needle.channelId === channelId);
const { id } = action;
const index = requests.findIndex(needle => needle.id === id);
if (index === -1) {
return state;
}

Просмотреть файл

@ -63,9 +63,7 @@ const EventSourceActor = ActorClassWithSpec(eventSourceSpec, {
// Implement functions of nsIEventSourceEventService.
eventSourceConnectionOpened(httpChannelId) {
this.emit("serverEventSourceConnectionOpened", httpChannelId);
},
eventSourceConnectionOpened(httpChannelId) {},
eventSourceConnectionClosed(httpChannelId) {
this.emit("serverEventSourceConnectionClosed", httpChannelId);

Просмотреть файл

@ -1099,6 +1099,16 @@ NetworkObserver.prototype = {
response.waitingTime = this._convertTimeToMs(
this._getWaitTiming(httpActivity.timings)
);
// Mime type needs to be sent on response start for identifying an sse channel.
const contentType = headers.find(header => {
const lowerName = header.toLowerCase();
return lowerName.startsWith("content-type");
});
if (contentType) {
response.mimeType = contentType.slice("Content-Type: ".length);
}
httpActivity.responseStatus = response.status;
httpActivity.headersSize = response.headersSize;

Просмотреть файл

@ -13,10 +13,6 @@ const eventSourceSpec = generateActorSpec({
*/
events: {
// In order to avoid a naming collision, we rename the server event.
serverEventSourceConnectionOpened: {
type: "eventSourceConnectionOpened",
httpChannelId: Arg(0, "number"),
},
serverEventSourceConnectionClosed: {
type: "eventSourceConnectionClosed",
httpChannelId: Arg(0, "number"),