Skip to content

Commit

Permalink
Merge pull request #66 from rstudio/bugfix/transfer-encoding-chunked
Browse files Browse the repository at this point in the history
Fix #64: invalid 'n' argument in upload
  • Loading branch information
jcheng5 committed Oct 29, 2014
2 parents a4ae283 + 488f85d commit 5bc15c7
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 8 deletions.
49 changes: 42 additions & 7 deletions R/rpubsUpload.R
Original file line number Diff line number Diff line change
Expand Up @@ -161,32 +161,67 @@ rpubsUpload <- function(title,
return (tarfile)
}

readResponse <- function(conn) {
# Use skipDecoding=TRUE if transfer-encoding: chunked but the
# chunk decoding has already been performed on conn
readResponse <- function(conn, skipDecoding) {
# read status code
resp <- readLines(conn, 1)
statusCode <- parseHttpStatusCode(resp[1])

# read response headers
contentLength <- NULL
location <- NULL
transferEncoding <- NULL
repeat {
resp <- readLines(conn, 1)
if (nzchar(resp) == 0)
break

header <- parseHeader(resp)
# Case insensitive header name comparison
headerName <- tolower(header$name)
if (!is.null(header)) {
if (identical(header$name, "Content-Type"))
if (identical(headerName, "content-type"))
contentType <- header$value
if (identical(header$name, "Content-Length"))
if (identical(headerName, "content-length"))
contentLength <- as.integer(header$value)
if (identical(header$name, "Location"))
if (identical(headerName, "location"))
location <- header$value
if (identical(headerName, "transfer-encoding"))
transferEncoding <- tolower(header$value)
}
}

# read the response content
content <- rawToChar(readBin(conn, what = 'raw', n=contentLength))
content <- if (is.null(transferEncoding) || skipDecoding) {
if (!is.null(contentLength)) {
rawToChar(readBin(conn, what = 'raw', n=contentLength))
}
else {
paste(readLines(conn, warn = FALSE), collapse = "\r\n")
}
} else if (identical(transferEncoding, "chunked")) {
accum <- ""
repeat {
resp <- readLines(conn, 1)
resp <- sub(";.*", "", resp) # Ignore chunk extensions
chunkLen <- as.integer(paste("0x", resp, sep = ""))
if (is.na(chunkLen)) {
stop("Unexpected chunk length")
}
if (identical(chunkLen, 0L)) {
break
}
accum <- paste0(accum, rawToChar(readBin(conn, what = 'raw', n=chunkLen)))
# Eat CRLF
if (!identical("\r\n", rawToChar(readBin(conn, what = 'raw', n=2)))) {
stop("Invalid chunk encoding: missing CRLF")
}
}
accum
} else {
stop("Unexpected transfer encoding")
}

# return list
list(status = statusCode,
Expand Down Expand Up @@ -231,7 +266,7 @@ rpubsUpload <- function(title,
writeBin(fileContents, conn, size=1)

# read the response
readResponse(conn)
readResponse(conn, skipDecoding = FALSE)
}


Expand Down Expand Up @@ -314,7 +349,7 @@ rpubsUpload <- function(title,
if (result == 0) {
fileConn <- file(outputFile, "rb")
on.exit(close(fileConn))
readResponse(fileConn)
readResponse(fileConn, skipDecoding = TRUE)
} else {
stop(paste("Upload failed (curl error", result, "occurred)"))
}
Expand Down
2 changes: 1 addition & 1 deletion markdown.Rproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ AlwaysSaveHistory: Default

EnableCodeIndexing: Yes
UseSpacesForTab: Yes
NumSpacesForTab: 2
NumSpacesForTab: 3
Encoding: UTF-8

RnwWeave: knitr
Expand Down

0 comments on commit 5bc15c7

Please sign in to comment.