summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Buckley-Houston <tom@tombh.co.uk>2018-08-02 19:26:09 +0800
committerThomas Buckley-Houston <tom@tombh.co.uk>2018-08-02 19:26:09 +0800
commit855d8daa41f96c37bcbbd047e28a50bc28ff45d6 (patch)
tree8589c14a55fa87d89af5ceda3cf003a4aadac895
parent4ebd7287ceec0ad2520c9d08a56676de8ef1b409 (diff)
Use thread-safe map for HTTP requestsv1.4.12
This fixes a race condition when may parallel requests are made to the HTTP service
-rw-r--r--interfacer/src/browsh/comms.go2
-rw-r--r--interfacer/src/browsh/raw_text_server.go42
-rw-r--r--interfacer/src/browsh/version.go2
3 files changed, 39 insertions, 7 deletions
diff --git a/interfacer/src/browsh/comms.go b/interfacer/src/browsh/comms.go
index 46c10bb..494af08 100644
--- a/interfacer/src/browsh/comms.go
+++ b/interfacer/src/browsh/comms.go
@@ -96,7 +96,7 @@ func handleRawFrameTextCommands(parts []string) {
}
if incoming.RequestID != "" {
Log("Raw text for " + incoming.RequestID)
- rawTextRequests[incoming.RequestID] = incoming.RawJSON
+ rawTextRequests.store(incoming.RequestID, incoming.RawJSON)
} else {
Log("Raw text but no associated request ID")
}
diff --git a/interfacer/src/browsh/raw_text_server.go b/interfacer/src/browsh/raw_text_server.go
index 1aab195..a2b3d4c 100644
--- a/interfacer/src/browsh/raw_text_server.go
+++ b/interfacer/src/browsh/raw_text_server.go
@@ -2,6 +2,7 @@ package browsh
import (
"crypto/rand"
+ "sync"
"encoding/json"
"fmt"
"io"
@@ -20,7 +21,37 @@ import (
// In order to communicate between the incoming HTTP request and the websocket request to the
// real browser to render the webpage, we keep track of requests in a map.
-var rawTextRequests = make(map[string]string)
+var rawTextRequests = newRequestsMap()
+
+type threadSafeRequestsMap struct {
+ sync.RWMutex
+ internal map[string]string
+}
+
+func newRequestsMap() *threadSafeRequestsMap {
+ return &threadSafeRequestsMap{
+ internal: make(map[string]string),
+ }
+}
+
+func (m *threadSafeRequestsMap) load(key string) (value string, ok bool) {
+ m.RLock()
+ result, ok := m.internal[key]
+ m.RUnlock()
+ return result, ok
+}
+
+func (m *threadSafeRequestsMap) store(key string, value string) {
+ m.Lock()
+ m.internal[key] = value
+ m.Unlock()
+}
+
+func (m *threadSafeRequestsMap) remove(key string) {
+ m.Lock()
+ delete(m.internal, key)
+ m.Unlock()
+}
type rawTextResponse struct {
PageloadDuration int `json:"page_load_duration"`
@@ -136,7 +167,7 @@ func handleHTTPServerRequest(w http.ResponseWriter, r *http.Request) {
return
}
rawTextRequestID := pseudoUUID()
- rawTextRequests[rawTextRequestID+"-start"] = start
+ rawTextRequests.store(rawTextRequestID+"-start", start)
mode := getRawTextMode(r)
sendMessageToWebExtension(
"/raw_text_request," + rawTextRequestID + "," +
@@ -211,16 +242,17 @@ func waitForResponse(rawTextRequestID string, w http.ResponseWriter) {
var totalTime, pageLoad, parsing string
var ok bool
for {
- if rawTextRequestResponse, ok = rawTextRequests[rawTextRequestID]; ok {
+ if rawTextRequestResponse, ok = rawTextRequests.load(rawTextRequestID); ok {
jsonResponse = unpackResponse(rawTextRequestResponse)
- totalTime = getTotalTiming(rawTextRequests[rawTextRequestID+"-start"])
+ requestStart, _ := rawTextRequests.load(rawTextRequestID+"-start")
+ totalTime = getTotalTiming(requestStart)
pageLoad = fmt.Sprintf("%d", jsonResponse.PageloadDuration)
parsing = fmt.Sprintf("%d", jsonResponse.ParsingDuration)
w.Header().Set("X-Browsh-Duration-Total", totalTime)
w.Header().Set("X-Browsh-Duration-Pageload", pageLoad)
w.Header().Set("X-Browsh-Duration-Parsing", parsing)
io.WriteString(w, jsonResponse.Text)
- delete(rawTextRequests, rawTextRequestID)
+ rawTextRequests.remove(rawTextRequestID)
break
}
time.Sleep(1 * time.Millisecond)
diff --git a/interfacer/src/browsh/version.go b/interfacer/src/browsh/version.go
index 8b02007..53537e8 100644
--- a/interfacer/src/browsh/version.go
+++ b/interfacer/src/browsh/version.go
@@ -1,3 +1,3 @@
package browsh
-var browshVersion = "1.4.11"
+var browshVersion = "1.4.12"