2017-02-28 21:32:23 +00:00
|
|
|
import React, {PureComponent, PropTypes} from 'react';
|
2017-03-12 00:31:23 +00:00
|
|
|
import mime from 'mime-types';
|
2017-03-03 01:44:07 +00:00
|
|
|
import autobind from 'autobind-decorator';
|
2017-03-08 05:52:17 +00:00
|
|
|
import KeyValueEditor from '../key-value-editor/editor';
|
2017-03-09 06:23:23 +00:00
|
|
|
import Editor from '../codemirror/code-editor';
|
2016-11-23 19:33:24 +00:00
|
|
|
import {trackEvent} from '../../../analytics/index';
|
2016-08-22 20:05:42 +00:00
|
|
|
|
2017-03-12 00:31:23 +00:00
|
|
|
let mimesSet = {};
|
|
|
|
for (const t of Object.keys(mime.types)) {
|
|
|
|
mimesSet[mime.types[t]] = 1;
|
|
|
|
}
|
|
|
|
const allMimeTypes = Object.keys(mimesSet);
|
|
|
|
|
2017-03-03 01:44:07 +00:00
|
|
|
@autobind
|
2017-02-28 21:32:23 +00:00
|
|
|
class RequestHeadersEditor extends PureComponent {
|
2017-03-03 01:44:07 +00:00
|
|
|
_handleBulkUpdate (headersString) {
|
2016-08-22 20:05:42 +00:00
|
|
|
this.props.onChange(this._getHeadersFromString(headersString));
|
2017-03-03 01:44:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_handleTrackToggle (pair) {
|
|
|
|
trackEvent('Headers Editor', 'Toggle', pair.disabled ? 'Disable' : 'Enable');
|
|
|
|
}
|
|
|
|
|
|
|
|
_handleTrackCreate () {
|
|
|
|
trackEvent('Headers Editor', 'Create');
|
|
|
|
}
|
2016-11-29 22:28:55 +00:00
|
|
|
|
2017-03-03 01:44:07 +00:00
|
|
|
_handleTrackDelete () {
|
|
|
|
trackEvent('Headers Editor', 'Delete');
|
|
|
|
}
|
2016-08-22 20:05:42 +00:00
|
|
|
|
|
|
|
_getHeadersFromString (headersString) {
|
|
|
|
const headers = [];
|
|
|
|
const rows = headersString.split(/[\n,]+/);
|
|
|
|
|
|
|
|
for (const row of rows) {
|
|
|
|
const items = row.split(':');
|
|
|
|
|
2017-03-03 20:09:08 +00:00
|
|
|
if (items.length !== 2) {
|
2016-08-22 20:05:42 +00:00
|
|
|
// Need a colon to be valid
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const name = items[0].trim();
|
|
|
|
const value = items[1].trim();
|
|
|
|
|
|
|
|
if (!name || !value) {
|
|
|
|
// Need name and value to be valid
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
headers.push({name, value});
|
|
|
|
}
|
|
|
|
|
|
|
|
return headers;
|
|
|
|
}
|
|
|
|
|
|
|
|
_getHeadersString () {
|
|
|
|
const {headers} = this.props;
|
|
|
|
|
|
|
|
let headersString = '';
|
|
|
|
|
|
|
|
for (const header of headers) {
|
2016-11-22 19:43:36 +00:00
|
|
|
// Make sure it's not disabled
|
|
|
|
if (header.disabled) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure it's a valid header (key + value)
|
|
|
|
if (!header.name || !header.value) {
|
2016-08-22 20:05:42 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
headersString += `${header.name}: ${header.value}\n`;
|
|
|
|
}
|
|
|
|
|
|
|
|
return headersString;
|
|
|
|
}
|
|
|
|
|
2017-03-12 00:31:23 +00:00
|
|
|
_getCommonHeaderValues (pair) {
|
|
|
|
if (pair.name.toLowerCase() === 'content-type') {
|
|
|
|
return allMimeTypes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_getCommonHeaderNames (pair) {
|
|
|
|
return [
|
|
|
|
'Accept',
|
|
|
|
'Accept-Charset',
|
|
|
|
'Accept-Encoding',
|
|
|
|
'Accept-Language',
|
|
|
|
'Accept-Datetime',
|
|
|
|
'Authorization',
|
|
|
|
'Cache-Control',
|
|
|
|
'Connection',
|
|
|
|
'Cookie',
|
|
|
|
'Content-Length',
|
|
|
|
'Content-MD5',
|
|
|
|
'Content-Type',
|
|
|
|
'Date',
|
|
|
|
'Expect',
|
|
|
|
'Forwarded',
|
|
|
|
'From',
|
|
|
|
'Host',
|
|
|
|
'If-Match',
|
|
|
|
'If-Modified-Since',
|
|
|
|
'If-None-Match',
|
|
|
|
'If-Range',
|
|
|
|
'If-Unmodified-Since',
|
|
|
|
'Max-Forwards',
|
|
|
|
'Origin',
|
|
|
|
'Pragma',
|
|
|
|
'Proxy-Authorization',
|
|
|
|
'Range',
|
|
|
|
'Referer',
|
|
|
|
'TE',
|
|
|
|
'User-Agent',
|
|
|
|
'Upgrade',
|
|
|
|
'Via',
|
|
|
|
'Warning'
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2016-08-22 20:05:42 +00:00
|
|
|
render () {
|
2017-03-12 00:31:23 +00:00
|
|
|
const {
|
|
|
|
bulk,
|
|
|
|
headers,
|
|
|
|
onChange,
|
|
|
|
handleRender,
|
|
|
|
handleGetRenderContext
|
|
|
|
} = this.props;
|
2016-08-22 20:05:42 +00:00
|
|
|
|
|
|
|
return bulk ? (
|
2017-03-01 00:10:23 +00:00
|
|
|
<div className="tall">
|
|
|
|
<Editor
|
|
|
|
onChange={this._handleBulkUpdate}
|
2017-03-01 21:15:56 +00:00
|
|
|
defaultValue={this._getHeadersString()}
|
2016-09-22 20:02:29 +00:00
|
|
|
/>
|
|
|
|
</div>
|
2017-03-01 00:10:23 +00:00
|
|
|
) : (
|
|
|
|
<div className="pad-bottom scrollable-container">
|
|
|
|
<div className="scrollable">
|
2017-03-03 20:09:08 +00:00
|
|
|
<KeyValueEditor
|
|
|
|
sortable
|
|
|
|
namePlaceholder="My-Header"
|
|
|
|
valuePlaceholder="Value"
|
|
|
|
pairs={headers}
|
|
|
|
handleRender={handleRender}
|
2017-03-12 00:31:23 +00:00
|
|
|
handleGetRenderContext={handleGetRenderContext}
|
|
|
|
handleGetAutocompleteNameConstants={this._getCommonHeaderNames}
|
|
|
|
handleGetAutocompleteValueConstants={this._getCommonHeaderValues}
|
2017-03-03 20:09:08 +00:00
|
|
|
onToggleDisable={this._handleTrackToggle}
|
|
|
|
onCreate={this._handleTrackCreate}
|
|
|
|
onDelete={this._handleTrackDelete}
|
|
|
|
onChange={onChange}
|
|
|
|
/>
|
2017-03-01 00:10:23 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
2016-08-22 20:05:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RequestHeadersEditor.propTypes = {
|
|
|
|
onChange: PropTypes.func.isRequired,
|
|
|
|
bulk: PropTypes.bool.isRequired,
|
2017-02-27 21:00:13 +00:00
|
|
|
handleRender: PropTypes.func.isRequired,
|
2017-03-12 00:31:23 +00:00
|
|
|
handleGetRenderContext: PropTypes.func.isRequired,
|
2016-08-22 20:05:42 +00:00
|
|
|
headers: PropTypes.arrayOf(PropTypes.shape({
|
|
|
|
name: PropTypes.string.isRequired,
|
|
|
|
value: PropTypes.string.isRequired
|
|
|
|
})).isRequired
|
|
|
|
};
|
|
|
|
|
|
|
|
export default RequestHeadersEditor;
|